out(泛型修饰符)(C# 参考)out (generic modifier) (C# Reference)

对于泛型类型参数,out 关键字可指定类型参数是协变的。For generic type parameters, the out keyword specifies that the type parameter is covariant. 可以在泛型接口和委托中使用 out 关键字。You can use the out keyword in generic interfaces and delegates.

协变使你使用的类型可以比泛型参数指定的类型派生程度更大。Covariance enables you to use a more derived type than that specified by the generic parameter. 这样可以隐式转换实现协变接口的类以及隐式转换委托类型。This allows for implicit conversion of classes that implement covariant interfaces and implicit conversion of delegate types. 引用类型支持协变和逆变,但值类型不支持它们。Covariance and contravariance are supported for reference types, but they are not supported for value types.

具有协变类型参数的接口使其方法返回的类型可以比类型参数指定的类型派生程度更大。An interface that has a covariant type parameter enables its methods to return more derived types than those specified by the type parameter. 例如,因为在 .NET Framework 4 的 IEnumerable<T> 中,类型 T 是协变的,所以可以将 IEnumerable(Of String) 类型的对象分配给 IEnumerable(Of Object) 类型的对象,而无需使用任何特殊转换方法。For example, because in .NET Framework 4, in IEnumerable<T>, type T is covariant, you can assign an object of the IEnumerable(Of String) type to an object of the IEnumerable(Of Object) type without using any special conversion methods.

可以向协变委托分配相同类型的其他委托,不过要使用派生程度更大的泛型类型参数。A covariant delegate can be assigned another delegate of the same type, but with a more derived generic type parameter.

有关详细信息,请参阅协变和逆变For more information, see Covariance and Contravariance.

示例 - 协变泛型接口Example - covariant generic interface

下面的示例演示如何声明、扩展和实现协变泛型接口。The following example shows how to declare, extend, and implement a covariant generic interface. 它还演示如何对实现协变接口的类使用隐式转换。It also shows how to use implicit conversion for classes that implement a covariant interface.

// 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;
    }
}

在泛型接口中,如果类型参数满足以下条件,则可以声明为协变:In a generic interface, a type parameter can be declared covariant if it satisfies the following conditions:

  • 类型参数只用作接口方法的返回类型,而不用作方法参数的类型。The type parameter is used only as a return type of interface methods and not used as a type of method arguments.

    备注

    此规则有一个例外。There is one exception to this rule. 如果在协变接口中将逆变泛型委托用作方法参数,则可以将协变类型用作此委托的泛型类型参数。If in a covariant interface you have a contravariant generic delegate as a method parameter, you can use the covariant type as a generic type parameter for this delegate. 有关协变和逆变泛型委托的详细信息,请参阅委托中的变体对 Func 和 Action 泛型委托使用变体For more information about covariant and contravariant generic delegates, see Variance in Delegates and Using Variance for Func and Action Generic Delegates.

  • 类型参数不用作接口方法的泛型约束。The type parameter is not used as a generic constraint for the interface methods.

示例 - 协变泛型委托Example - covariant generic delegate

以下示例演示如何声明、实例化和调用协变泛型委托。The following example shows how to declare, instantiate, and invoke a covariant generic delegate. 它还演示如何隐式转换委托类型。It also shows how to implicitly convert delegate types.

// 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(); 
}

在泛型委托中,如果类型仅用作方法返回类型,而不用于方法参数,则可以声明为协变。In a generic delegate, a type can be declared covariant if it is used only as a method return type and not used for method arguments.

C# 语言规范C# language specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification. 该语言规范是 C# 语法和用法的权威资料。The language specification is the definitive source for C# syntax and usage.

请参阅See also