显式实现的接口和通用约束
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;
}
}
实际编译的代码有什么区别(CallHidden1 与 CallHidden2)吗? 在访问显式实现的接口成员方面, where T : Foo 和 where T : Foo, IBar (如果 Foo 实现了 IBar)之间还有其他区别吗?
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 ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
生成的 IL 略有不同:
与
如果
T
是值类型,这将导致foo
被装箱在CallHidden1
中,但不会在 <代码>CallHidden2。但是,由于Foo
是一个类,因此从Foo
派生的任何类型T
都不会是值类型,因此行为将是相同的。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.是的,有一点点,因为第二个指定必须实现该接口,如果以后更改
Foo
使其不实现IBar
,这一点可能会变得很重要。这将使其不适合在
CallHidden2
中使用,同时在编译时对CallHidden1
保持有效(如果IBar 则在运行时会失败)
不再由Foo
实现)。因此,如果它们位于不同的程序集中,不同的元数据将会产生影响。然而,执行的 IL 即使不相同,也将非常相似。
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.