我有:
class Person
{
public Person(string name, int age)
{
this.Name = name;
}
public string Name { get; set; }
public virtual void Speak()
{
Console.Write("Hello I am a person");
}
public static T GenerateRandomInstance<T>() where T: Person
{
var p = new T("hello", 4); // error does not compile
// rondomize properties
return p;
}
}
class Student : Person
{
// constructor I call the base class here
public Student(string name, int age)
: base(name, age)
{
}
public override void Speak()
{
Console.Write("Hello I am a student");
}
}
我遇到的问题是当我这样做时:
Student.GenerateRandomInstance();
我得到Person
而不是Student
。如何修复GenerateRandomInstance
方法,使其返回Student而不是Person。 将一个人投给学生会给我一个错误
答案 0 :(得分:5)
你做不到。静态方法不能在子类中重写,并且无法区分Student.GenerateRandomInstance
和Person.GenerateRandomInstance
- 实际上它们在编译时会生成完全相同的CIL。
您可以使用通用方法:
public static T GenerateRandomInstance<T>() where T : Person, new
{
var p = new T();
// randomize properties
return p;
}
Person.GenerateRandomInstance<Student>();
但是这只有在类型具有无参数构造函数时才有效。如果您想将参数传递给构造函数,则会变得更加困难。假设您始终知道要将哪些值传递给构造函数,则可以执行以下操作:
public static T GenerateRandomInstance<T>() where T : Person
{
var p = (T)Activator.CreateInstance(typeof(T), "hello", 4);
// randomize properties
return p;
}
当然,如果指定的类型不包含合适的构造函数,这也将失败。
答案 1 :(得分:2)
尝试这样的事情。 Person
和Student
各自定义了自己的GenerateRandomInstance
和RandomizeProperties
方法。 Student
调用Person
的{{1}}让基类随机化其知道的属性。 RandomizeProperties
只会随机化Student
类引入的属性。
注意:此问题通常由Abstract Factory或Builder设计模式解决。下面的解决方案都不是那些。
Student
答案 2 :(得分:1)
您需要覆盖Student类中的GenerateRandomInstance()
方法。目前正在调用Person中的基本方法。