繁体   English   中英

C#多态性问题

[英]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。 如果你没有坚持这个设计,我会重构出静态方法。 静态似乎很容易,不幸的是有很多代码'质量'工具推动你使方法静态,忘记提醒你以后不能轻易地将静态方法改为虚方法。

允许BA的构造函数中传递A DTO对象。 如果需要,请使构造函数protected 然后,让BDAD

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM