簡體   English   中英

StackOverflowException使用具有協變泛型參數的explict接口實現

[英]StackOverflowException by using explict interface implementation having covariant generic parameter

我正在使用協變泛型參數擴展現有的IClonable接口。

public interface ICloneable<out T> : ICloneable
{
    new T Clone();
}

現在我在基類中實現了這個接口。

public class Base : ICloneable<Base>
{
    public string StrValue { get; set; }

    Base ICloneable<Base>.Clone()
    {
        var result = (Base)FormatterServices.GetUninitializedObject(this.GetType());
        result.StrValue = this.StrValue;
        return result;
    }

    public virtual object Clone()
    {
        return ((ICloneable<Base>)this).Clone();
    }
}

調用Clone()按預期工作並返回具有相同值的基類的新實例。

我創建了一個Base的派生類,它再次實現接口ICloneable<T>以返回這個新類型:

public class Sub : Base, ICloneable<Sub>
{
    public int IntValue { get; set; }

    Sub ICloneable<Sub>.Clone()
    {
        var result = (Sub)base.Clone();
        result.IntValue = this.IntValue;
        return result;
    }

    public override object Clone()
    {
        return ((ICloneable<Sub>)this).Clone();
    }
}

但是,如果我調用Clone()上的一個實例Sub我碰上StackOverflowException因為object Base.Clone()調用Sub ICloneable<Sub>.Clone()類的Sub

問題是協變泛型類型參數。 如果我刪除out所有的作品如預期。

問題是為什么((ICloneable<Base>)this).Clone()指向Sub.Clone()

共同和逆變只有語法糖,編譯器在派生層次結構中搜索最低可能的類型嗎? 這意味着編譯器將ICloneable<Base>更改為ICloneable<Sub>

我沒有找到任何解釋這種行為的官方理由。

測試代碼(不包括接口和BaseSub ):

var b = new Sub { StrValue = "Hello World.", IntValue = 42 };
var b2 = (Base)b.Clone();

共同和逆變只有語法糖,編譯器在派生層次結構中搜索最低可能的類型嗎?

Co / contravariance與語法糖無關。 它允許您在編譯時傳遞“更小”,更具體的類型(協方差)和更大的(逆變)與特定的編譯器限制。

因為您的T參數被標記為out ,所以CLR將查看Clone任何覆蓋實現的運行時。

編譯時綁定是callvirtbase.Clone ,它不會改變:

.method public hidebysig newslot virtual 
instance object Clone () cil managed 
{
    // Method begins at RVA 0x2089
    // Code size 7 (0x7)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: callvirt instance !0 class ICloneable`1<class Base>::Clone()
    IL_0006: ret

} // end of method Base::Clone

運行時是多態發生的地方

,取消的事實out調用基強調,准確。

暫無
暫無

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

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