[英]Explicitly implemented interface and generic constraint
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)是實際編譯的代碼? T:Foo和T:Foo,IBar(如果Foo實現IBar)在訪問顯式實現的接口成員時是否存在其他差異?
產生的IL略有不同:
L_000d: ldarg.0
L_000e: box !!T
L_0013: callvirt instance void WindowsFormsApplication1.IBar::Hidden()
與
L_000d: ldarga.s foo
L_000f: constrained !!T
L_0015: callvirt instance void WindowsFormsApplication1.IBar::Hidden()
如果T
是值類型,這將導致foo
在CallHidden1
被裝箱但在CallHidden2
沒有CallHidden2
。 但是,由於Foo
是一個類,因此從Foo
派生的任何類型T
都不是值類型,因此行為將是相同的。
是的,一點點,因為第二個指定必須實現接口,如果稍后改變Foo
以使其不實現IBar
,這可能變得重要。
這將使它不適合在CallHidden2<>
使用,同時在編譯時為CallHidden1<>
保持有效(如果不再由Foo
實現IBar
,則會在運行時失敗)。
因此,如果它們位於不同的程序集中,則不同的元數據會有所不同。 然而,執行的IL將非常相似,如果不相同的話。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.