代码之家  ›  专栏  ›  技术社区  ›  Samvel Siradeghyan

动作<T>或动作<in T>?

  •  10
  • Samvel Siradeghyan  · 技术社区  · 15 年前

    我在读关于行动代表的文章 MSDN

     public delegate void Action<in T>(T obj);
    

    比我看到的 c-sharpcorner.com 它使用了这个语法

    public delegate void Action<T>(T obj);   
    

    in 在T。
    哪种语法是正确的 在里面
    EDIT:与 Predicate .

    谢谢。

    3 回复  |  直到 12 年前
        1
  •  10
  •   Motti    15 年前

    这个 in 部分用于 covariance and contravariance 它是在.NET 4.0中引入的,您链接到的文章是在.net4.0发布之前于2006年发布的(所以显然它没有提到co[ntra]方差)。

        2
  •  11
  •   Jon Skeet    15 年前

    in out (泛型协方差和协方差)仅在C#4中引入,并且对.NET 4的委托和接口进行了修改-所以 Action<T> 在.NET 3.5中 Action<in T>

    你所指的文章是2006年的,早在.NET 4问世之前。

    .NET 3.5 version 显示它没有 在里面

        3
  •  1
  •   supercat    12 年前

    值得注意的是,从概念上讲,所有委托类型在理论上都可以与任何仅用作返回类型的类型参数和仅用于通过值传递的方法参数的类型参数相反,并且编译器可以自动允许这种差异,但有一个问题除外:当 in Action 将防止编译器在 Action<Animal> 传递给期望 Action<Cat> ,一些方法希望 动作<Cat> 动作<动物> . 一般来说,如果方法能够正确地处理所有此类委托,则只应接受具有协方差/反方差说明符的类型的委托;否则,它们应接受不具有此类说明符的委托类型。

    大多数 接受 动作<Cat> 和一个 动作<动物> Action<T> 相反。因为许多方法都接受 EventHandler<T> 如果给出的东西与预期的类型不完全匹配,可能会失败得很严重, 事件处理程序<T> 不是相反的。

    回想起来,如果每个委托类型都定义了自己的 Combine CatEventArgs:AnimalEventArgs ,说

    EventHandler<CatEventArgs> myEvents=null;
    void AddEvent(EventHandler<CatEventArgs> newEvent)
    {
      myEvents = EventHandler<CatEventArgs>.Combine(myEvents, newEvent);
    }
    

    可能交了一个通行证 EventHandler<AnimalEventsArgs> EventHandler<CatEventArgs> ,然后可以与任何其他委托相结合,这些委托同样可以转换为 事件处理程序<CatEventArgs> . 不幸的是,自从 仅在上定义 Delegate ,不可能 方法可以知道调用代码需要什么委托类型[IMHO,即使没有协方差/反方差,让委托定义它们自己的类型也是很好的 联合收割机 Remove 方法,因为这样可以避免将 Delegate.Combine