[英]Does inheritance in generics work the same way as concrete and abstract classes, InvalidCaseException
[英]Inheritance question - declaring abstract and concrete versions of the same property
好的,有兩種選擇,但是在我開始之前,您需要了解這一點:
public abstract class GatewayBase { ... }
public class Gateway : GatewayBase { ... }
選擇#1
public abstract class ModelBase
{
public GatewayBase GatewayBase { get; private set; } // property named GatewayBase
public ModelBase(GatewayBase gateway)
{
GatewayBase = gateway;
}
}
public class Model : ModelBase
{
public Gateway Gateway { get; private set; } // property named Gateway
public Model(Gateway gateway)
: base(gateway)
{
Gateway = gateway;
}
}
選擇#2
public abstract class ModelBase
{
public GatewayBase Gateway { get; private set; } // property named Gateway
public ModelBase(GatewayBase gateway)
{
Gateway = gateway;
}
}
public class Model : ModelBase
{
public new Gateway Gateway { get; private set; } // property named Gateway plus "new" modifier
public Model(Gateway gateway)
: base(gateway)
{
Gateway = gateway;
}
}
討論:
使用替代方法#1,具體的類Model
可以“看到” Gateway
兩個版本。 一個稱為GatewayBase
,另一個稱為Gateway
,但是它們都包含完全相同的實例。 從技術上講,使用替代方法2,仍然有兩個版本的Gateway
但是一個版本隱藏了另一個版本,因此實際上只有一個版本(除非您使用base.Gateway
繞過它)。 我喜歡替代方法2,無論我在哪里,都可以將其稱為Gateway
屬性,因為它在基類和具體類中都得到了廣泛使用,並且它的名稱簡短但清晰。 盡管如此,我還是對以這種方式使用new
修飾符有些猶豫。 這真的是隱藏財產的合理方案嗎?
您會選擇哪一個?為什么?
或隨時建議其他選擇。
謝謝。
編輯:
我應該指出, GatewayBase
和ModelBase
是一個依賴程序集,所以他們不知道任何有關Gateway
和Model
。 然而, Gateway
和Model
當然知道GatewayBase
和ModelBase
。
選項2看起來更干凈,但是沒有單獨的支持屬性,而是通過將現有基類的屬性從GatewayBase投射到Gateway來包裝它。 這樣,您就不會對所使用的網關有任何歧義:只是從不同的角度來看,它始終是相同的:
public abstract class ModelBase
{
public ModelBase(GatewayBase gateway)
{
this.Gateway = gateway;
}
public GatewayBase Gateway { get; private set; }
}
public class Model : ModelBase
{
public Model(Gateway gateway)
: base(gateway)
{
}
public new Gateway { get { return (Gateway) base.Gateway; } }
}
您還可以使用泛型為不同類型的網關(有點像IEnumerable <T>)使事情變得更加靈活。 泛型的問題在於,您不能將一個C <X>轉換為另一個C <Y>(嗯,有時可以在4.0中轉換)。 解決此問題的最干凈方法是引入非泛型接口,您可以在泛型類上明確實現該接口。 這樣,當您與泛型實例通信時,它就不會顯示出來,但是您仍然可以混合使用C <X>和C <Y>。
public interface IModel
{
GatewayBase Gateway { get; }
}
public abstract class ModelBase<TGateway> : IModel
where T : GatewayBase
{
public ModelBase(TGateway gateway)
{
this.Gateway = gateway;
}
public TGateway Gateway { get; private set; }
GatewayBase IModel.Gateway { get { return this.Gateway; } }
}
public class Model : ModelBase<Gateway>
{
public Model(Gateway gateway)
: base(gateway)
{
}
}
我不確定為什么要第二個Gateway屬性。 網關是否具有與GatewayBase不同的接口? 如果是這樣,我會看到差異,但總的來說,我認為這可能不是最佳設計。 我會認真考慮網關是否應公開除GatewayBase之外的任何其他屬性/方法。 如果不是,則不需要Model.Gateway屬性。
最好僅在兩個類之間存在“是”關系時才使用繼承。 這意味着網關“是A” GatewayBase,並且通常應該具有相同的屬性/方法,至少是公共的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.