簡體   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