Usually, treating a struct S
as an interface I
will trigger autoboxing of the struct, which can have impacts on performance if done often. However, if I write a generic method taking a type parameter T : I
and call it with an S
, then will the compiler omit the boxing, since it knows the type S
and does not have to use the interface?
This code shows my point:
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?
}
}
The doFoo
method calls foo()
on an object of type I
, so once we call it with an S
, that S
will get boxed. The doFooGeneric
method does the same thing. However, once we call it with an S
, no autoboxing might be required, since the runtime knows how to call foo()
on an S
. But will this be done? Or will the runtime blindly box S
to an I
to call the interface method?
struct
constraint - ievoid doFooGeneric<T>(T t) where T : struct, I {
– PrincelyIsBoxed
function from this answer says that it's not boxed. I don't know the details of why though. – Shannonshannyt
is boxed in thet.foo()
call. – DissociatedoFooGeneric
? Like this? – Shannonshannyt
is not boxed inside the methoddoFooGeneric
. It does not show what happens whent.foo()
executes. Suppose we wrotet.ToString()
instead oft.foo()
. That would box because ourS
does notoverride
ToString
. Or if we hadt.GetType()
, that would always box (GetType()
is non-virtual so never overridden). – Dissociatet
was boxed indoFooGeneric
... I think I need to go read some more... – Shannonshanny