out(泛型修饰符)(C# 参考)
对于泛型类型参数,out
关键字可指定类型参数是协变的。 可以在泛型接口和委托中使用 out
关键字。
协变使你使用的类型可以比泛型参数指定的类型派生程度更大。 这样可以隐式转换实现协变接口的类以及隐式转换委托类型。 引用类型支持协变和逆变,但值类型不支持它们。
具有协变类型参数的接口使其方法返回的类型可以比类型参数指定的类型派生程度更大。 例如,因为在 .NET Framework 4 的 IEnumerable<T> 中,类型 T 是协变的,所以可以将 IEnumerable(Of String)
类型的对象分配给 IEnumerable(Of Object)
类型的对象,而无需使用任何特殊转换方法。
可以向协变委托分配相同类型的其他委托,不过要使用派生程度更大的泛型类型参数。
有关详细信息,请参阅协变和逆变。
示例 - 协变泛型接口
下面的示例演示如何声明、扩展和实现协变泛型接口。 它还演示如何对实现协变接口的类使用隐式转换。
// Covariant interface.
interface ICovariant<out R> { }
// Extending covariant interface.
interface IExtCovariant<out R> : ICovariant<R> { }
// Implementing covariant interface.
class Sample<R> : ICovariant<R> { }
class Program
{
static void Test()
{
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();
// You can assign istr to iobj because
// the ICovariant interface is covariant.
iobj = istr;
}
}
在泛型接口中,如果类型参数满足以下条件,则可以声明为协变:
类型参数只用作接口方法的返回类型,而不用作方法参数的类型。
注意
此规则有一个例外。 如果在协变接口中将逆变泛型委托用作方法参数,则可以将协变类型用作此委托的泛型类型参数。 有关协变和逆变泛型委托的详细信息,请参阅委托中的变体和对 Func 和 Action 泛型委托使用变体。
类型参数不用作接口方法的泛型约束。
示例 - 协变泛型委托
以下示例演示如何声明、实例化和调用协变泛型委托。 它还演示如何隐式转换委托类型。
// Covariant delegate.
public delegate R DCovariant<out R>();
// Methods that match the delegate signature.
public static Control SampleControl()
{ return new Control(); }
public static Button SampleButton()
{ return new Button(); }
public void Test()
{
// Instantiate the delegates with the methods.
DCovariant<Control> dControl = SampleControl;
DCovariant<Button> dButton = SampleButton;
// You can assign dButton to dControl
// because the DCovariant delegate is covariant.
dControl = dButton;
// Invoke the delegate.
dControl();
}
在泛型委托中,如果类型仅用作方法返回类型,而不用于方法参数,则可以声明为协变。
C# 语言规范
有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。