in(泛型修饰符)(C# 参考)
对于泛型类型参数,in
关键字可指定类型参数是逆变的。 可以在泛型接口和委托中使用 in
关键字。
逆变使你使用的类型可以比泛型参数指定的类型派生程度更小。 这样可以隐式转换实现协变接口的类以及隐式转换委托类型。 引用类型支持泛型类型参数中的协变和逆变,但值类型不支持它们。
仅在类型定义方法参数的类型,而不是方法返回类型时,类型可以在泛型接口或委托中声明为逆变。 In
、ref
和 out
参数必须是固定的,这意味着它们既不是协变的,也不是逆变的。
具有逆变类型参数的接口使其方法接受的参数的类型可以比接口类型参数指定的类型派生程度更小。 例如,在 IComparer<T> 接口中,类型 T 是逆变的,可以将 IComparer<Person>
类型的对象分配给 IComparer<Employee>
类型的对象,而无需使用任何特殊转换方法(如果 Employee
继承 Person
)。
可以向逆变委托分配相同类型的其他委托,不过要使用派生程度更小的泛型类型参数。
有关详细信息,请参阅协变和逆变。
逆变泛型接口
下面的示例演示如何声明、扩展和实现逆变泛型接口。 它还演示如何对实现此接口的类使用隐式转换。
// Contravariant interface.
interface IContravariant<in A> { }
// Extending contravariant interface.
interface IExtContravariant<in A> : IContravariant<A> { }
// Implementing contravariant interface.
class Sample<A> : IContravariant<A> { }
class Program
{
static void Test()
{
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;
}
}
逆变泛型委托
以下示例演示如何声明、实例化和调用逆变泛型委托。 它还演示如何隐式转换委托类型。
// Contravariant delegate.
public delegate void DContravariant<in A>(A argument);
// Methods that match the delegate signature.
public static void SampleControl(Control control)
{ }
public static void SampleButton(Button button)
{ }
public void Test()
{
// Instantiating the delegates with the methods.
DContravariant<Control> dControl = SampleControl;
DContravariant<Button> dButton = SampleButton;
// You can assign dControl to dButton
// because the DContravariant delegate is contravariant.
dButton = dControl;
// Invoke the delegate.
dButton(new Button());
}
C# 语言规范
有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。