簡體   English   中英

明確實現的接口和泛型約束

[英]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是值類型,這將導致fooCallHidden1被裝箱但在CallHidden2沒有CallHidden2 但是,由於Foo是一個類,因此從Foo派生的任何類型T都不是值類型,因此行為將是相同的。

是的,一點點,因為第二個指定必須實現接口,如果稍后改變Foo以使其不實現IBar ,這可能變得重要。

這將使它不適合在CallHidden2<>使用,同時在編譯時為CallHidden1<>保持有效(如果不再由Foo實現IBar ,則會在運行時失敗)。

因此,如果它們位於不同的程序集中,則不同的元數據會有所不同。 然而,執行的IL將非常相似,如果不相同的話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM