c# – 无法将委托转换为泛型类型T.

前端之家收集整理的这篇文章主要介绍了c# – 无法将委托转换为泛型类型T.前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
为什么我们不能将委托的实例强制转换为泛型类型T?

考虑一个实用程序方法CreateDelegate,它创建一个T实例,它是一个委托,即从MulticastDelegate派生的类型.

T CreateDelegate<T>() {… }

不幸的是,泛型不允许将T约束到从MulticastDelegate派生的类型,从而产生以下编译错误

Constraint cannot be special class ‘System.MulticastDelegate’

然而,这个实用程序方法检查T是否与MulticastDelegate兼容并通过Reflection通过Delegate :: CreateDelegate创建委托.但是,如果我们尝试将Delegate :: CreateDelegate的结果强制转换为T,我们将得到以下编译错误

Cannot convert type ‘System.Delegate’ to ‘T’

但是,如果我首先将它转换为对象然后转换为T它将正常工作:

T h = (T) ((object) Delegate.CreateDelegate(typeof(T),target,m));

为什么我们不能直接将代表委托给T?

解决方法

C#语言强制静态检查从类型X到类型Y的强制转换是否有效 – 即它是否有意义,因为编译器可以(在某种程度上)保证兼容性并拒绝编译时清除的错误.无约束的泛型类型T和System.Delegate没有任何直接的共同点.但是,当转换为对象时,编译器知道每个类型实际上都是一个对象,因此它允许转换.这并不意味着在特定情况下运行时类型检查不会失败.

as运算符稍微宽松一点,因为它不会导致其他无效转换的异常.编译器在应用静态检查时也不那么严格.在您的特定情况下,这很有用,因为您可以省略对象的中间强制转换并将其用作T.但是,这需要的是仅适用于类类型,因此您必须应用where T:class约束.

所以这个方法看起来像这样(简化):

public T CreateDelegate<T>(…) where T : class
{
    return Delegate.CreateDelegate(typeof(T),…) as T;
}

正如@usr建议的那样,推荐读物是Eric Lippert的博客,例如: this article on casts and type parameters.

猜你在找的C#相关文章