协方差和反方差匿名类型

本文关键字:类型 方差匿 方差 | 更新日期: 2023-09-27 18:28:09

我在C#中了解到,covariance and contravariance为数组类型、委托类型和泛型类型参数启用了隐式引用转换。

我想知道我可以使用匿名类型(直接从对象派生的类类型)的协方差和反方差吗?这是如何工作的?

协方差和反方差匿名类型

我可以使用匿名类型的泛型接口和委托的协方差和逆变差吗?

是的。匿名类型是引用类型;差异仅适用于引用类型。

如何?

接口协方差:

var sequenceOfAnonymous = from c in customers select new {c.Name, c.Age};
var sequenceOfObject = (IEnumerable<object>)sequenceOfAnonymous;

阵列协方差:

var arrayOfAnonymous = sequenceOfAnonymous.ToArray();
var arrayOfObject = (object[]) arrayOfAnonymous;

为了证明委托协方差,你需要使用一个通用的类型推理技巧:

static Func<R> MakeFunc(Func<R> f) { return f; }
...
var funcOfAnonymous = MakeFunc( ()=>new { X = 123 } );
var funcOfObject = (Func<object>)funcOfAnonymous;

接口差异需要一个稍微不同的技巧:通过示例进行投射:

interface IFrobber<in T> { void Frob(T t); }
class Frobber<T> : IFrobber<T> 
{ 
    public void Frob(T t) { Console.WriteLine(t); }
}
...
static IFrobber<T> FrobByExample<T>(IFrobber<T> frobber, T example) 
{ return frobber; }
...
var frobberOfObject = new Frobber<object>();
var frobberOfAnonymous = FrobByExample(frobberOfObject, new { X = 0 });

同样,对于委托相反:

static Action<A> ActionByExample<A>(Action<A> action, A example) 
{ return action; }
...
var actionOfObject = (Action<object>) x => { Console.WriteLine(x); }
var actionOfAnonymous = ActionByExample(actionOfObject, new { X = 0 } );

有道理吗?