1

I am familiar with Generics and Generics constraints etc in C#, well at least I thought so until I seen this. I was looking at this Interface in the Fluent Validation Library and it threw me, what does this line of code mean?

public interface IValidator<in T> : IValidator, IEnumerable<IValidationRule>, IEnumerable

specifically the <in T> snippet of code.

Here is the full interface for reference. (http://fluentvalidation.codeplex.com/SourceControl/latest#src/FluentValidation/IValidator.cs)

#region 

Assembly FluentValidation.dll, v4.0.30319

#endregion

using FluentValidation.Results;
using System.Collections;
using System.Collections.Generic;

namespace FluentValidation
{
    // Summary:
    //     Defines a validator for a particualr type.
    //
    // Type parameters:
    //   T:
    public interface IValidator<in T> : IValidator, IEnumerable<IValidationRule>, IEnumerable
    {
        // Summary:
        //     Sets the cascade mode for all rules within this validator.
        CascadeMode CascadeMode { get; set; }

        // Summary:
        //     Validates the specified instance.
        //
        // Parameters:
        //   instance:
        //     The instance to validate
        //
        // Returns:
        //     A ValidationResult object containing any validation failures.
        ValidationResult Validate(T instance);
    }
}
SimonGates
  • 5,961
  • 4
  • 40
  • 52
  • 1
    When you typed "C# generics in T" into your favored search engine in your probable first line of research, were those results not helpful? – Anthony Pegram May 16 '13 at 14:38
  • 1
    Why didn't you type those words or something like them into your favored search engine, then? Keep in mind, we expect you to conduct your own research prior to asking questions. The downvote tooltip text *starts* with "this question does not show any research effort." – Anthony Pegram May 16 '13 at 14:45

4 Answers4

3

With in keyword, T is defined as contra-variant parameter:

An interface that has a contra-variant type parameter allows its methods to accept arguments of less derived types than those specified by the interface type parameter

If you are familiar with built-int delegate Action and Func. Input parameter type of Action and Func are defined as contra-variant

Example from MSDN:

interface IContravariant<in T> where T: class { }
class Sample<T> : IContravariant<T> { }

IContravariant<Object> iobj = new Sample<Object>();
IContravariant<String> istr = new Sample<String>();

// You can assign iobj to istr because 
// the IContravariant interface is contravariant.
istr = iobj; //compile successfully

If you don't define T as contra-vanriant, T is called invariant, and the below assignment will get compiled error:

// In-variant interface. 
interface IInvariant<T> where T: class { }
class Sample<T> : IInvariant<T> where T: class { } 

IInvariant<object> iobj = new Sample<object>();
IInvariant<string> istr = new Sample<string>();

istr = iobj; // compile error

More information about co-variant and contra-variant from here

Please notice that co-variant and contra-variant only supports on reference type, not value type.

Community
  • 1
  • 1
cuongle
  • 74,024
  • 28
  • 151
  • 206
0

Contravariance is enforced in relation a particular generic type parameter, is using the in generic modifier.

http://www.codeproject.com/Articles/72467/C-4-0-Covariance-And-Contravariance-In-Generics

Andrey
  • 59,039
  • 12
  • 119
  • 163
0

The in keyword specifies that the type parameter is contravariant. Go to below link for more details.

http://msdn.microsoft.com/en-us/library/dd469484.aspx

Guanxi
  • 3,103
  • 21
  • 38
0

It specifies that this type parameter is a variant. Check variance and contravariance. Basically it tells the compiler that when creating a method based on this generic, in addition to the declared type, it will also accept any type that derives frpm the declared type (if it uses the word in), or any type that the declared type derives from, (if it uses the new keyword out)

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216