【发布时间】:2016-02-10 17:09:46
【问题描述】:
为什么我们不能将 delegate 的实例转换为泛型类型T?
考虑一个实用方法CreateDelegate,它创建一个T的实例,它是一个委托,即从MulticastDelegate派生的类型。
T CreateDelegate<T>() {… }
不幸的是,泛型不允许将 T 约束为派生自 MulticastDelegate 的类型,会出现以下编译错误:
约束不能是特殊类'System.MulticastDelegate'
不过,此实用程序方法正在检查 T 是否与 MulticastDelegate 兼容,并通过 Delegate::CreateDelegate 的反射创建委托。但是,如果我们尝试将Delegate::CreateDelegate 的结果强制转换为T,我们会得到如下编译错误:
无法将类型“System.Delegate”转换为“T”
但是,如果我先将其转换为object,然后再转换为T,它将正常工作:
T h = (T) ((object) Delegate.CreateDelegate(typeof(T), target, m));
为什么我们不能直接将委托强制转换为 T?
【问题讨论】:
-
这行得通吗:
T h = Delegate.CreateDelegate(typeof(T), target, m) as T;? -
是的,这行得通。而且,它更没有意义。恕我直言,两个运算符(
as和 cast)的行为应该是一致的。 -
这种方式比将对象转换为 T 更安全,如果转换失败,它会给你 null
-
有时抛出
Exception是期望的行为,而不是返回null。 -
有 Eric Lippert 关于这个主题的帖子。如果您对语言设计特别是 C# 感兴趣,请阅读所有 Erics 博客。