代码之家  ›  专栏  ›  技术社区  ›  Raghav

C多态性问题

  •  3
  • Raghav  · 技术社区  · 16 年前

    我有一个bl类,名为:a,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。在达尔,我写过:

    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中获得新扩展的属性(示例中的名称)吗?

    5 回复  |  直到 16 年前
        1
  •  4
  •   nandokakimoto    16 年前

    当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);
            }
    
        2
  •  3
  •   Jason Kleban    16 年前

    如果对象实际上是基类型,则不能只附加附加附加属性。不是那样的,对不起。

    你想要的是转换对象(也许)。在子类中创建一个构造函数,该构造函数可以获取父类并将其所有内容复制到自身中,这样您就拥有了额外的属性。

        3
  •  3
  •   Guffa    16 年前

    强制转换失败的原因是,您没有将mydto对象传递给方法,而是将dto对象传递给方法。myblmethod方法总是将dto对象发送到dal,即使存在mydto对象。

    您尚未将d属性设为虚拟。这意味着在引用上使用d属性时,即使实际对象发生在a b实例上,也会得到a类所包含的d to对象,从而使它也具有mydto对象。

    您可以使d属性为虚拟的,以访问实际对象的d属性,而不是由引用类型指定的属性。

    或者您可以将引用强制转换为b,这样您就可以访问它的mydto对象而不是dto对象:

    static void MyBLMethod(A b) {
       MyDALMethod(((B)b).D);
    }
    

    注意,B类同时包含DTO和MyDTO对象,这可能不是您真正想要的。

        4
  •  2
  •   Jim L    16 年前

    听起来您正在失去“分辨率”,因为您正在传递静态业务逻辑方法。我建议重新审视这一部分,而不是先尝试DAL方法。

    但是,可能有一个原因让您坚持这样做,所以如果您坚持这样做,您可以考虑使用反射来查找所需的属性,或者使用“as”强制转换,然后在DAL方法中测试空值。如果您不坚持这种设计,那么我将重构出静态方法。静态看起来很容易,不幸的是,有很多代码“质量”工具促使您使方法成为静态的,忘记提醒您以后不能轻易地将静态方法更改为虚拟方法。

        5
  •  1
  •   strager    16 年前

    允许 B 通过 A DTO 对象在 的构造函数。如果需要,请创建构造函数 protected . 然后,有 B.D 铸造 A.D .

    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; }
        }
    }