簡體   English   中英

C#:覆蓋屬性並返回派生類型

[英]C# : Override a property and return a derived type

假設我有一個帶有屬性“Details”的A類,它返回一個B類實例。

public class A
{
    public virtual B Details {get; set;}
}

也可以說,我有一個繼承自A的Aext(擴展)類。但我希望Aext.Details返回類Bext的實例(B擴展):

public class Aext : A
{
    public override Bext Details {get; set;}
}

這將無法編譯,因為Bext類型必須與從A繼承的類型匹配。
當然,我只需將B作為Aext的詳細信息返回即可輕松解決。

public class Aext
{
    B Details {get; set;}
}

分配將起作用,但如果Details是Bext或B,我每次使用Aext的實例時都要檢查。

你有沒有看到這種解決方案做得更清潔的方法?

謝謝。

也許你可以嘗試泛型,像這樣:

public class A<T> where T : B
{
    public T Details { get; set; }
}

public class Aext : A<Bext>
{
}

public class B
{

}

public class Bext : B
{

}

如果您需要,可以使用Bext Details覆蓋T詳細信息,它將正常工作。

不 - 但我認為這表明基類在設計上存在缺陷。 您正在嘗試將接口行為強制轉換為Abstract類/方法。 基本方法什么都不做,究竟是什么繼承? 基類可以具有由每個繼承者訪問的類型B的受保護成員,並通過其自己的強類型訪問器方法公開。 該值可供所有繼承者使用,但消費者需要獲取/設置強類型版本的數據。

如果您不想引入接口,可以執行以下操作:

public class B
{ }

public class Bext : B
{ }

public class A
{
    public virtual B Details { get; set; }

    public A()
    {
        Details = new B();
    }

}

public class Aext : A
{
    public override B Details => new Bext();
}

但是,我建議你使用組合並使用依賴注入,如下所示:

public interface IB
{ }
public class B : IB
{ }

public class Bext : IB
{ }

public class A
{
    public virtual IB Details { get; set; }

    public A(IB details)
    {
        Details = details;
    }
}

public class TestClass
{
    public void TestMethod()
    {
        IB details = new B();
        IB extDetails = new Bext();

        A instance1 = new A(details);
        A instance2 = new A(extDetails);
    }
}

這樣,您無需通過創建Aext類來擴展繼承層次結構。 您可以嚴格包含相關屬性。

暫無
暫無

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

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