簡體   English   中英

在C#中實例化動態類型

[英]Instantiate a dynamic Type in C#

我有一個Animal類和兩個派生類: LionAnt

我有一個采用Animal類型的方法,我想返回傳遞給函數的動物派生類型的新實例(即Lion的新實例)。

public Animal Reproduce(Animal p_animal)
{
    Type animalType = p_animal.GetType();

    if (SameSpecies(p_animal)) 
        return new animalType(RandomName());
}

有幾種方法可以實現此目的,但是我建議您在Animal類上創建一個抽象的Reproduce方法,並在派生類型中實現它。 例如:

public abstract class Animal
{
    /* .. other stuff .. */
    public abstract Animal Reproduce();
    public string RandomName() { /* ... */ }
}

public class Lion : Animal
{
    /*... other stuff .. */
    public override Animal Reproduce() => new Lion(RandomName());
}

這樣,您可以在特定於特定AnimalReproduce方法中添加任何將來的邏輯

由於您在編譯時不知道類型 ,因此必須使用Reflection。 您可以嘗試實現以下目標:

return (Animal)Activator.CreateInstance(animalType, RandomName());

該行在運行時執行,這意味着,如果類型“ animalType”實際上不是類“ Animal”的擴展,則此行將在運行時失敗。 同樣,類型為“ animalType”的構造函數之一需要恰好接收一個無論“類型”(RandomName())函數返回的參數,否則您還將遇到運行時錯誤。

編輯:反射會降低性能,應該盡可能避免。 KMoussa建議您遵循的一種很好的方法可以避免反射,因此比反射方法好得多。

您可以使用反射,也可以保持某種類型的安全性,並使用一種稱為“好奇地重復出現的模板模式”的東西。 它使用泛型,如果您不熟悉該概念,我會做一些閱讀,因為它們在.Net Eco系統中非常強大,有用且普遍。 無論如何,這就是我會做的

public abstract class Animal<T> 
    where T : Animal<T>
{
    public string Name {get; private set;}
    public Animal(string name)
    {
        Name = name;
    }

    public abstract T Reproduce();  

    public static T Reproduce(T animalToReproduce)
    {
        return animalToReproduce.Reproduce();
    }

}

public class Lion : Animal<Lion>
{
    public Lion(string name)
        : base (name)
    {

    }
    public override Lion Reproduce()
    {
        return new Lion(RandomName());
    }

}

然后,您可以只調用Animal.Reproduce(yourAnimalInstance)這將返回正確類型的對象。 例如

Lion myLion = GetALionFromSomewhere();
Lion babyLion = Animal.Reproduce(myLion);

它將編譯,並且您具有類型安全性的所有優點

暫無
暫無

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

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