【发布时间】:2015-07-16 14:52:46
【问题描述】:
通常,将结构 S 视为接口 I 将触发结构的自动装箱,如果经常这样做可能会对性能产生影响。但是,如果我编写一个带有类型参数T : I 的泛型方法并使用S 调用它,那么编译器会省略装箱,因为它知道S 的类型并且不必使用接口?
这段代码说明了我的观点:
interface I{
void foo();
}
struct S : I {
public void foo() { /* do something */ }
}
class Y {
void doFoo(I i){
i.foo();
}
void doFooGeneric<T>(T t) where T : I {
t.foo(); // <--- Will an S be boxed here??
}
public static void Main(string[] args){
S x;
doFoo(x); // x is boxed
doFooGeneric(x); // x is not boxed, at least not here, right?
}
}
doFoo 方法在I 类型的对象上调用foo(),所以一旦我们用S 调用它,S 就会被装箱。 doFooGeneric 方法做同样的事情。然而,一旦我们用S 调用它,就不需要自动装箱,因为运行时知道如何在S 上调用foo()。但这会完成吗?或者运行时会盲目地将S 绑定到I 以调用接口方法?
【问题讨论】:
-
尝试添加
struct约束 - 即void doFooGeneric<T>(T t) where T : struct, I { -
FWIW,使用来自this answer 的
IsBoxed函数表示它没有装箱。我不知道为什么的细节。 -
相关(如果不重复):stackoverflow.com/questions/3032750/…,特别是 Marc Gravell 的 this answer
-
@JamesThorpe 据我所知,您不能使用该方法查看
t是否在t.foo()调用中被装箱。 -
@JeppeStigNielsen 你不会……你会在
doFooGeneric里面做吗? Like this?
标签: c# generics interface autoboxing