interface IBar { void Hidden(); }
class Foo : IBar { public void Visible() { /*...*/ } void IBar.Hidden() { /*...*/ } }
class Program
{
static T CallHidden1<T>(T foo) where T : Foo
{
foo.Visible();
((IBar)foo).Hidden(); //Cast required
return foo;
}
static T CallHidden2<T>(T foo) where T : Foo, IBar
{
foo.Visible();
foo.Hidden(); //OK
return foo;
}
}
Is there any difference (CallHidden1 vs. CallHidden2) is actual compiled code? Is there other differences between where T : Foo and where T : Foo, IBar (if Foo implements IBar) that in accessing explicitly implemented interface members ?
The IL generated is slightly different:
vs.
If
T
were a value type, this would result infoo
being boxed inCallHidden1
but not inCallHidden2
. However, sinceFoo
is a class, any typeT
derived fromFoo
will not be a value type, and thus the behavior will be identical.Yes, a tiny bit, since the second specifies that the interface must be implemented, which may become important if
Foo
is later changed so that it does not implementIBar
.That would make it unsuitable for being used in
CallHidden2<>
while remaining valid at compile time forCallHidden1<>
(which would then fail at runtime ifIBar
is no longer being implemented byFoo
).So if they are in separate assemblies, the different metadata would make a difference. The executed IL will, however, be pretty similar if not the same.