我熟悉C#中的泛型和泛型约束等,至少我是这么认为的,直到我看到它。我在Fluent验证库中查看了这个界面,它告诉我,这行代码是什么意思?
public interface IValidator<in T> : IValidator, IEnumerable<IValidationRule>, IEnumerable
特别是<in T>
代码段。
这是完整的参考界面。 (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);
}
}
答案 0 :(得分:3)
使用in
关键字,T
被定义为 contra-variant 参数:
具有contra-variant类型参数的接口允许其方法接受派生类型少于接口类型参数
指定的派生类型的参数
如果您熟悉built-int delegate Action
和Func
。输入参数类型Action
和Func
定义为 contra-variant
来自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
如果你没有将T定义为 contra-vanriant ,则T被称为 invariant ,并且以下赋值将被编译错误:
// 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
有关here
的共变体和反变体的更多信息请注意co-variant and contra-variant only supports on reference type, not value type.
答案 1 :(得分:0)
对比特定的泛型类型强制实施逆变 参数,使用in generic修饰符。
http://www.codeproject.com/Articles/72467/C-4-0-Covariance-And-Contravariance-In-Generics
答案 2 :(得分:0)
in关键字指定type参数是逆变的。 请转到以下链接了解更多详情。
答案 3 :(得分:0)
它指定此类型参数是变体。检查variance and contravariance。基本上它告诉编译器在创建基于此泛型的方法时,除了声明的类型之外,它还将接受任何派生frpm声明类型的类型(如果它使用单词in
),或任何类型声明的类型派生自(如果它使用新关键字out
)