“where T : Delegate”或“where T : MulticastDelegate”是什么意思?

5
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.MulticastDelegate,因为没有从前者而不是后者派生的类型。 - fghzxm
3
我听到的故事是,最初它旨在通过将单播和多播分为不同类型来优化存储。实际上,只有多播被使用,所以他们从未添加过其他类型。现在拥有这两种类型没有任何意义,但它们存在是出于历史原因。你的两个声明之间应该没有区别。 - Lasse V. Karlsen
1
关于类型参数约束,where T : System.Delegate 就足够了。在 MulticastDelegate 中所有公共方法都是对虚拟 Delegate 方法的重写(或者像等式操作符一样,转给一个方法去处理)。任何你需要使用 T 的地方都可以得到 MulticastDelegate 的实现。甚至静态方法 Delegate.CombineDelegate.Remove 都会调用被 MulticastDelegate 重写的虚拟方法。 - madreflection
1个回答

3

我们无法实例化DelegateMulticastDelegate类,因为这些类是抽象的

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

 public abstract class MulticastDelegate : Delegate { ... }

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

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

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

即使您无法直接创建派生类,但您将使用这些类上定义的方法。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接