【问题标题】:`where T : Delegate` or `where T : MulticastDelegate`?`where T:Delegate` 还是`where T:MulticastDelegate`?
【发布时间】:2020-01-24 07:23:45
【问题描述】:

C# 7.3 添加了support 用于将泛型类型参数约束为委托类型。

public class UsingDelegate<T> where T : System.Delegate { }
public class Multicaster<T> where T : System.MulticastDelegate { }

这可能是微不足道的,但where T : System.Delegatewhere T : System.MulticastDelegate 之间有什么实际区别吗?这在 Microsoft Docs 中没有记录。

【问题讨论】:

  • 我很想进一步问为什么首先有单独的System.DelegateSystem.MulticastDelegategiventhat 没有从前者派生的类型而不是从后者派生的类型.
  • 我听到的故事是,它最初是一种优化存储的方法,通过不同类型的单次转换和多次转换。在实践中,只使用了多重演员,所以他们从不添加其他类型。现在拥有这两种类型没有意义,但由于历史原因它们存在。你的两个声明应该没有区别。
  • 关于类型参数约束,where T : System.Delegate 就足够了。 MulticastDelegate 中的所有公共内容都是虚拟 Delegate 方法的覆盖(或遵循一个,如相等运算符的情况)。您需要对T 执行的任何操作都将获得MulticastDelegate 实现。即使是静态的Delegate.CombineDelegate.Remove 方法也遵循被MulticastDelegate 覆盖的虚拟实现。

标签: c# .net generics delegates


【解决方案1】:

我们无法实例化 DelegateMulticastDelegate 类,因为这些类是 abstract

 public abstract class Delegate : ICloneable, ISerializable { ... }

 public abstract class MulticastDelegate : Delegate { ... }

使用代理的主要方式是delegate 关键字。当我们使用 C# 语言关键字 delegate 声明委托类型时,C# 编译器会创建派生自 MulticastDelegate 的类的实例。

The reason of why C# compiler creates instances of a class derived from MulticastDelegate is:

这种设计源于 C# 和 .NET 的第一个版本。一 设计团队的目标是确保语言强制类型 使用代表时的安全性。这意味着确保代表 使用正确的类型和数量的参数调用。而且,任何 在编译时正确指示了返回类型。代表们是 1.0 .NET 版本的一部分,在泛型之前。

强制执行这种类型安全的最佳方法是让编译器 创建代表该方法的具体委托类 正在使用的签名。

即使你不能直接创建派生类,你也会使用 这些类上定义的方法。

可以看出,委托是 1.0 .NET 版本的一部分,该版本早于泛型,因此可以得出结论,由于历史原因,C# 7.3 中存在约束 where T : System.Delegate { } 以强制执行通过创建代表正在使用的方法签名的具体委托类来确保编译器的类型安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2012-06-15
    相关资源
    最近更新 更多