WEB开发网
开发学院软件开发C语言 [C# 4.0] 5. Covariance & Contravariance 阅读

[C# 4.0] 5. Covariance & Contravariance

 2010-09-30 21:07:01 来源:WEB开发网   
核心提示: 泛型委托逆变示例 2classBase{publicintX{get;set;}}classDerived:Base{}delegatevoidTestHandler<inT>(To);classProgram{staticvoidMain(string[]args){TestHan

泛型委托逆变示例 2

class Base
{
  public int X { get; set; }
}
class Derived : Base
{
}
delegate void TestHandler<in T>(T o);
class Program
{
  static void Main(string[] args)
  {
    TestHandler<Base> _base = (o) => Console.WriteLine(o.X);
    TestHandler<Derived> _derived = _base;
    _derived(new Derived());
  }
}

泛型接口逆变示例

interface ITest<in T>
{
  void M(T o);
}
class TestClass<T> : ITest<T>
  where T : Base
{
  public void M(T o)
  {
    Console.WriteLine(o.X);
  }
}
class Base
{
  public int X { get; set; }
}
class Derived : Base
{
}
class Program
{
  static void Main(string[] args)
  {
    ITest<Base> _base = new TestClass<Base>();
    ITest<Derived> _derived = _base;
    _derived.M(new Derived { X = 12345 });
  }
}

和委托一样,泛型接口的逆变同样是在 in 的约束下为原本 Base 类型的参数提供 Derived 对象,因此隐式转换没有什么问题。

Func<Derived> _derived1 = () => new Derived();
Func<Base> _base1 = _derived1; // Covariance: [out] Derived -> Base
Base obj = _base1();
Action<Base> _base2 = (o) => { };
Action<Derived> _derived2 = _base2; // Contravariant: [in] Base -> Derived
_derived2(new Derived());
Func<Base, Derived> _source = (o) => new Derived();
Func<Derived, Base> _target = _source; // Covariant return, Contravariant parameter
Base obj2 = _target(new Derived());

除上述规则外,泛型协变和逆变还须遵循如下规则:

* In the .NET Framework version 4 Beta 2, variant type parameters are restricted to generic interface and generic delegate types.

* A generic interface or generic delegate type can have both covariant and contravariant type parameters.

* Variance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.

* Variance does not apply to delegate combination. That is, given two delegates of types Action<Derived> and Action<Base>, you cannot combine the second delegate with the first although the result would be type safe. Variance allows the second delegate to be assigned to a variable of type Action<Derived>, but delegates can combine only if their types match exactly.

相关细节可参考 MSDN。

上一页  1 2 3 4 5 

Tags:Covariance amp Contravariance

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接