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

对于泛型类型参数,out 关键字指定该类型参数是协变的。 可以在泛型接口和委托中使用 out 关键字。

通过协变,可以使用与泛型参数指定的派生类型相比,派生程度更大的类型。 这样可以对委托类型和实现变体接口的类进行隐式转换。 引用类型支持协变和逆变,但值类型不支持。

如果接口具有协变类型形参,则允许其方法返回与接口类型形参指定的派生类型相比,派生程度更大的类型的实参。 例如,由于在 .NET Framework 4 的 IEnumerable<T> 接口中,类型 T 是协变的,因此无需使用任何特殊转换方法就可以将 IEnumerabe(Of String) 类型的对象分配给 IEnumerable(Of Object) 类型的对象。

可以向协变委托分配同一类型的其他委托,但需使用派生程度较大的泛型类型参数。

有关更多信息,请参见 协变和逆变(C# 和 Visual Basic)

示例

下例演示如何声明、扩展和实现一个协变泛型接口。 此外还演示了如何对实现协变接口的类使用隐式转换。

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

在泛型接口中,当符合下列条件时,可以将类型参数声明为是协变的。

下例演示如何声明、实例化和调用一个协变泛型委托。 此外还演示了如何隐式转换委托类型。

// 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# 语言规范是 C# 语法和用法的权威资料。

请参见

参考

in(泛型修饰符)(C# 参考)

修饰符(C# 参考)

概念

泛型接口中的变体(C# 和 Visual Basic)