[英]C# polymorphism issue
我有一個名為:A的BL類,名為DTO的DTO類。 現在假設我想在我的DTO中添加更多屬性。 所以我從現有的DTO中派生出一個新的DTO類,並為它添加屬性。下面是代碼:
namespace TestConsole
{
class test
{
static void Main(string[] args)
{
B b = new B();
b.D.ID = 1;
b.D.Name = "4";
MyBLMethod(b);
}
static void MyBLMethod(A b)
{
MyDALMethod(b.D);
}
static void MyDALMethod(DTO dto)
{
int i = dto.ID;
string name = ((MyDTO)dto).Name;//I could not do this
//because i will get object cast error as i can't cast from
//parent to child
}
}
public class DTO
{
public int ID = 99;
public DTO()
{
}
public DTO(DTO source)
{
ID = source.ID;
}
}
public class MyDTO : DTO
{
public string Name = "";
public MyDTO() { }
public MyDTO(MyDTO source)
: base(source)
{
Name = source.Name;
}
}
public class A
{
private DTO _d;
public A()
{
D = new DTO();
}
public DTO D
{
get { return _d; }
set { _d = value; }
}
}
public class B : A
{
private MyDTO _md;
public B()
{
_md = new MyDTO();
}
public MyDTO D
{
get { return _md; }
set { _md = value; }
}
}
}
從Main(您可以將其視為UI)我調用MyBLMethod(存在於BL存儲庫中)並將類對象傳遞給它,並且從BL存儲庫調用我的DAL。 在DAL我寫了這個:
static void MyDALMethod(DTO dto)
{
int i = dto.ID;
string name = ((MyDTO)dto).Name;//I could not do this
//because i will get object cast error as i can't cast from
//parent to child
}
你能建議我怎樣才能在我的DAL中獲得新擴展的屬性(示例中的名稱)。
當B繼承A時,它已經擁有DTO屬性。 所以問題實際上是你隱藏了這個繼承。 您不需要B類中的新屬性,只需在類構造函數中設置它即可。
public class B : A
{
public B()
{
this.D = new MyDTO();
}
}
但是,在您的主要課程中,您需要在您的屬性中進行顯式轉換,就像下面一樣,因為DTO沒有“Name”屬性。
static void Main(string[] args)
{
B b = new B();
b.D.ID = 1;
((MyDTO)b.D).Name = "4";
MyBLMethod(b);
}
如果對象實際上是基本類型,則不能僅僅添加其他屬性。 這樣做不對,抱歉。
你想要的是轉換對象(也許)。 在您的子類中創建一個構造函數,該構造函數可以將父項並將其全部復制到自身中 - 然后您將擁有其他屬性。
轉換失敗的原因是您沒有將MyDTO對象傳遞給方法,而是傳遞DTO對象。 即使存在MyDTO對象,MyBLMethod方法也始終將DTO對象發送到DAL。
您尚未將D屬性設為虛擬。 這意味着當您在A引用上使用D屬性時,即使實際對象發生在B實例上,您也可以獲得A類包含的DTO對象,以便它也具有MyDTO對象。
您可以使D屬性虛擬化以訪問實際對象的D屬性,而不是由引用類型指定的屬性。
或者您可以將引用轉換為B,以便您可以訪問它的MyDTO對象而不是它的DTO對象:
static void MyBLMethod(A b) {
MyDALMethod(((B)b).D);
}
請注意,B類包含DTO和MyDTO對象,這可能不是您真正想要的。
聽起來你正在失去“分辨率”,因為你正在通過靜態業務邏輯方法。 我建議重新審視那部分,而不是先用DAL方法進行掙扎。
可能有一個原因讓你堅持下去,所以如果你這樣做,你可以考慮使用反射來找到你需要的屬性,或者使用“as”強制轉換然后在你的dal方法中測試null。 如果你沒有堅持這個設計,我會重構出靜態方法。 靜態似乎很容易,不幸的是有很多代碼'質量'工具推動你使方法靜態,忘記提醒你以后不能輕易地將靜態方法改為虛方法。
允許B
在A
的構造函數中傳遞A
DTO
對象。 如果需要,請使構造函數protected
。 然后,讓BD
投AD
。
public class A
{
private DTO _d;
// New constructor.
protected A(DTO d)
{
_d = d;
}
// Old constructor calls new constructor.
public A() : this(new DTO())
{
}
public DTO D
{
get { return _d; }
set { _d = value; }
}
}
public class B : A
{
// Old B constructor calls new A constructor.
public B() : base(new MyDTO())
{
}
new public MyDTO D
{
// Getting D casts A.D instead of using an object exclusive to B.
get { return (MyDTO)base.D; }
set { base.D = value; }
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.