我有一个Animal
类和两个派生类:Lion
和Ant
。
我有一个采用Animal
类型的方法,我想返回传递给函数的动物派生类型的新实例(即Lion
的新实例)。 / p>
public Animal Reproduce(Animal p_animal)
{
Type animalType = p_animal.GetType();
if (SameSpecies(p_animal))
return new animalType(RandomName());
}
答案 0 :(得分:4)
有几种方法可以实现此目的,但是我建议您在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());
}
这样,您就可以在特定于特定Reproduce
的{{1}}方法中添加任何将来的逻辑
答案 1 :(得分:3)
由于您在编译时不知道类型,因此必须使用Reflection。您可以尝试通过以下方法实现目标:
return (Animal)Activator.CreateInstance(animalType, RandomName());
该行在运行时执行,这意味着,如果类型“ animalType”实际上不是类“ Animal”的扩展,则此行将在运行时失败。另外,您的“ animalType”类型的构造函数之一需要恰好接收一个返回“ RandomName()”类型的函数的参数,否则您将遇到运行时错误。
编辑:反射会降低性能,因此应尽可能避免。 KMoussa建议您可以采用一种避免反射的好方法,因此比反射方法好得多。
答案 2 :(得分:0)
您可以使用反射,也可以保持某种类型的安全性,并使用一种称为“好奇地重复的模板模式”的东西。它使用泛型,如果您不熟悉该概念,我会做一些阅读,因为它们在.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);
可以编译,并且您具有类型安全性的所有优点