我在MSDN上读到有关操作委托的内容,所以这篇文章的语法是
public delegate void Action<in T>(T obj);然后我在c-sharpcorner.com中查找,它使用以下语法
public delegate void Action<T>(T obj); 如你所见,在T之前没有in。
哪种语法是正确的,in是什么意思?
编辑:与Predicate使用的语法相同。
谢谢。
发布于 2010-11-02 15:01:37
in部分是针对covariance and contravariance的,它是在.NET 4.0中引入的,您所链接的文章是在2006年.NET 4.0发布之前发布的(所以它显然没有提到矛盾)。
发布于 2010-11-02 15:02:06
in和out (通用逆方差和协方差)只在C# 4中引入,并且在.NET 4中修改了委托和接口-因此.NET 3.5中的Action<T>在.NET 4中变为Action<in T>。
你提到的这篇文章是2006年的,在.NET 4问世之前很久。
如果您更改正在显示的MSDN的版本,您将看到更改-例如,.NET 3.5 version显示它而不显示in。
发布于 2013-10-10 00:31:18
值得注意的是,从概念上讲,从理论上讲,所有委托类型与仅用作返回类型的任何类型参数本质上是协变的,对于仅用于通过值传递的方法参数的类型参数是逆变的,编译器可以自动允许这种差异,但有一个问题除外:虽然Action的in声明将防止编译器在将Action<Animal>传递给需要Action<Cat>的方法时发出响声,但如果给出Action<Cat>,则某些需要Action<Animal>的方法可能会表现得非常糟糕。一般来说,方法应该只接受带有协方差/逆方差说明符的类型的委托,如果它们将正确地与所有这样的委托一起工作;否则它们应该接受没有这样的说明符的委托类型。
大多数接受Action<Cat>的方法在Action<Animal>上都可以很好地工作,所以微软决定追溯地使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结果进行类型转换。
https://stackoverflow.com/questions/4075535
复制相似问题