为什么我们不能将委托的实例转换为泛型类型T?
考虑一个CreateDelegate创建T实例的实用程序方法,它是一个委托,即派生自的类型MulticastDelegate.
T CreateDelegate<T>() {… }
Run Code Online (Sandbox Code Playgroud)
不幸的是,泛型不允许约束T到从MulticastDelegate给出以下编译错误派生的类型:
约束不能是特殊类'System.MulticastDelegate'
然而,这种实用方法是检查T与MulticastDelegateReflection through 兼容并创建委托Delegate::CreateDelegate.但是,如果我们尝试将结果转换Delegate::CreateDelegate为T,我们将得到以下编译错误:
无法将类型'System.Delegate'转换为'T'
但是,如果我先将它转换为object然后T它会正常工作:
T h = (T) ((object) Delegate.CreateDelegate(typeof(T), target, m));
Run Code Online (Sandbox Code Playgroud)
为什么我们不能直接将代表委托给T?
Ond*_*cny 12
C#语言强制静态检查从类型X到类型Y的强制转换是否有效 - 即它是否有意义,因为编译器可以(在某种程度上)保证兼容性并拒绝编译时清除的错误.一种不受约束的泛型类型T,System.Delegate没有任何直接的共同点.但是,当转换object为编译器时,知道每个类型都是一个object,所以它允许转换.这并不意味着在特定情况下运行时类型检查不会失败.
该as运营商是更宽容一点点,因为它会不会引起否则,无效转换异常.编译器在应用静态检查时也不那么严格.在您的特定情况下,这很有用,因为您可以省略中间强制转换object和使用as T.但是,需要的是as仅适用于类类型,因此必须应用where T : class约束.
所以这个方法看起来像这样(简化):
public T CreateDelegate<T>(…) where T : class
{
return Delegate.CreateDelegate(typeof(T), …) as T;
}
Run Code Online (Sandbox Code Playgroud)
正如@usr建议的那样,推荐读物是Eric Lippert的博客,例如关于强制转换和类型参数的文章.
| 归档时间: |
|
| 查看次数: |
1255 次 |
| 最近记录: |