簡體   English   中英

傳遞基類列表並獲取具體類

[英]Passing a list of base class and obtain the concrete class

我有兩個從基類派生的具體類。 與混凝土B級相比,混凝土A級具有十個附加屬性。 我有一個方法,其中參數之一是基類列表,例如: List<baseClass> 在方法內部,我必須遍歷列表,並將其轉換為適當的具體類並訪問屬性。 請讓我知道如何實現這一目標。 有沒有好的設計模式可以做到這一點?

C#有一個您可以研究的GetType方法。

你也有is運算符

if (baseClass is derivedClass)
{
    // do what you will with derived class.
}

通常,首先您要做的是不良的設計模式。 當您遍歷基類然后轉換為派生類時,多態性的整個點都會丟失。

也許您可以在基類中創建一個可以執行所需操作的方法。

這是基本方法:

foreach(baseClass x in theList)
{
   if (x is classA)
   {
       classA a = (classA) x;
       ...
   }
   else if (x is classB)
   {
       classB b = (classA) x;
       ...    
   }
}

當您需要拆分多種類型時,它並沒有變得更加簡單。 您可以嘗試避免使用接口或其他繼承模型來避免整個問題。 無法看到更多細節就無法准確說出。

我想C#的動態類型可以在這里成為您的朋友。

class BaseClass {}

class ConcreteClass1 : BaseClass
{
    void Display1 () {}
}

class ConcreteClass2 : BaseClass
{
    void Display2 () {}
}

void Enumerate (List<BaseClass> baseItems)
{
    foreach (BaseClass baseItem in baseItems)
    {
        ConcreteAccessor ((dynamic)baseItem);
    }
}

void ConcreteAccessor (ConcreteClass1 concreteItem1)
{
    concreteItem1.Display1 ();
}

void ConcreteAccessor (ConcreteClass2 concreteItem2)
{
    concreteItem2.Display2 ();
}    

這里的關鍵是每個具體類都有一個不同的重載,並使用dynamic以無縫方式調用其中一個。 這樣做的好處是可以在運行時解決重載,使您的代碼看起來更干凈。

因為它是運行時類型解析,所以不執行編譯時驗證。 假設您錯過一種具體類型的重載,並且運行時將baseItem解析為該特定具體類型。 然后,它將導致運行時錯誤-崩潰-因為沒有過載。

還有一個問題是動態使用引擎蓋下的反射。 如您所知,反射會降低您的應用程序速度。

foreach(var baseClass in baseClasses)
{
    if(baseClass.GetType() == typeof(ClassA)
    {
       var myClassA = (ClassA) baseClass;
        dowork();
    }
    else if(baseClass.GetType() == typeof(ClassB)
    {
       var myClassB = (ClassB) baseClass;
        dowork();
    }

}

為了避免顯式轉換,我建議您以其他方式進行處理:在基類中,添加一個將與具體類的屬性一起使用的抽象方法。

例如:

public abstract void DoSomethingUsingProperties();

在您的具體類中,使用正確的業務邏輯來實現(覆蓋)它。

然后,在參數之一是基類列表的方法中您可以執行以下操作:

public void YourMethod(List<BaseClass> list, ...other params)
{
    // ...

    foreach(var bc in list)
    {
        // so you don't need to know specific properties of concrete classes...
        bc.DoSomethingUsingProperties();
    }

    //...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM