[英]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.