【发布时间】:2011-09-21 18:01:25
【问题描述】:
假设我有一个通用方法:
T Foo(T x) {
return x;
}
到目前为止一切顺利。但如果它是一个 Hashtable,我想做一些特别的事情。 (我知道这是一个完全人为的例子。Foo() 也不是一个非常令人兴奋的方法。一起玩。)
if (typeof(T) == typeof(Hashtable)) {
var h = ((Hashtable)x); // CS0030: Cannot convert type 'T' to 'System.Collections.Hashtable'
}
该死。不过,公平地说,我实际上无法判断这是否应该是合法的 C#。那么,如果我尝试用不同的方式来做呢?
if (typeof(T) == typeof(Hashtable)) {
var h = x as Hashtable; // works (and no, h isn't null)
}
这有点奇怪。根据 MSDN,expression as Type 与expression is type ? (type)expression : (type)null 相同(除了计算表达式两次)。
如果我尝试使用文档中的等效表达式会怎样?
if (typeof(T) == typeof(Hashtable)) {
var h = (x is Hashtable ? (Hashtable)x : (Hashtable)null); // CS0030: Cannot convert type 'T' to 'System.Collections.Hashtable'
}
我看到的强制转换和as 之间唯一记录的区别是“as 运算符仅执行引用转换和装箱转换”。也许我需要告诉它我正在使用引用类型?
T Foo(T x) where T : class {
var h = ((Hashtable)x); // CS0030: Cannot convert type 'T' to 'System.Collections.Hashtable'
return x;
}
发生了什么事?为什么as 工作正常,而强制转换甚至无法编译?演员表应该起作用,还是 as 不起作用,或者演员表和 as 之间是否存在其他语言差异,而这些差异不在我发现的这些 MSDN 文档中?
【问题讨论】:
-
我很确定你从 MSDN 引用的那句话在泛型之前就已经存在了。
-
不过,如果仅此而已...肯定是个有趣的问题!
-
这是一个骗子,还是只是密切相关:stackoverflow.com/questions/884315/…?
-
我会说它是相关的——我是从另一个方向来的。如果是这样的话,这不是我第一次尝试遵循过时的 MSDN 文档!
-
@Ken:我认为另一个问题的标题是倒退的,在我看来实际上是一样的情况。
标签: c# generics c#-4.0 casting