【发布时间】:2012-03-17 01:19:57
【问题描述】:
我在 C# 中读到过,covariance and contravariance 为数组类型、委托类型和泛型类型参数启用隐式引用转换。
我想知道我可以对匿名类型(它们是直接从对象派生的类类型)使用协变和逆变吗?它是如何工作的?
【问题讨论】:
我在 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 } );
有意义吗?
【讨论】: