[英]Action<T> or Action<in T>?
我在MSDN上阅读有关Action Delegate的内容,以及语法下的内容
public delegate void Action<in T>(T obj);
比我查看c-sharpcorner.com并使用了这种语法
public delegate void Action<T>(T obj);
正如你可以看到有没有in
T.之前
其语法是正确的,那有什么in
是什么意思?
编辑:与Predicate
相同的语法。
谢谢。
in
与out
(通用逆变和协方差)在C#4只引入,代表和接口被修改为.NET 4 -所以Action<T>
在.NET 3.5成为Action<in T>
在.NET 4。
您所指的文章是从2006年开始的,早在.NET 4发布之前。
如果你改变你显示其MSDN版本,你会看到的变化-例如, .NET 3.5版本,表明它没有in
。
该in
部分是协方差和逆变 ,并介绍了在.NET 4.0中,你链接到被刊登在2006年之前,.NET 4.0的文章被释放(所以显然它并不是指合作[NTRA]方差)。
值得注意的是,从概念上讲,所有委托类型在理论上可以与任何类型参数本质上协变,这些参数仅用作返回类型和关于仅用于通过值传递的方法参数的类型参数的逆变,并且编译器可以自动允许这样的方差,除了一个问题:当in
声明Action
将阻止编译器如果嘎嘎叫Action<Animal>
被传递到期望的一个方法Action<Cat>
,一些方法期望的Action<Cat>
可以非常恶劣如果给出一个Action<Animal>
。 一般而言,如果方法能够与所有这些代表一起正确地工作,那么这些方法应该只接受具有协方差/逆变规范的类型的代表; 否则他们应该接受没有这些说明符的委托类型。
接受Action<Cat>
大多数方法都可以在Action<Animal>
正常工作,因此Microsoft决定追溯性地使Action<T>
逆变。 因为许多接受EventHandler<T>
方法如果给出与预期类型不完全匹配的任何东西,可能会非常糟糕地失败,因此EventHandler<T>
不会成为逆变。
回想起来,如果每个代表类型都定义了自己的Combine
方法,那么几乎在所有情况下都可以使代表协方差和逆变成功。 如果CatEventArgs:AnimalEventArgs
,说
EventHandler<CatEventArgs> myEvents=null;
void AddEvent(EventHandler<CatEventArgs> newEvent)
{
myEvents = EventHandler<CatEventArgs>.Combine(myEvents, newEvent);
}
可以将传入的EventHandler<AnimalEventsArgs>
转换为EventHandler<CatEventArgs>
,然后可以将其与任何其他委托组合,这些委托同样可以转换为EventHandler<CatEventArgs>
。 不幸的是,由于Combine
只在Delegate
定义,因此Combine
方法无法知道调用代码需要什么委托类型[恕我直言,即使没有协方差/逆变,如果委托人定义他们自己的Combine
会很不错和Remove
方法,因为这样就不需要对Delegate.Combine
的结果进行类型转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.