静态方法返回包含类类型的对象

时间:2013-07-31 20:16:59

标签: c# inheritance polymorphism

我有:

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。 将一个人投给学生会给我一个错误

3 个答案:

答案 0 :(得分:5)

你做不到。静态方法不能在子类中重写,并且无法区分Student.GenerateRandomInstancePerson.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)

尝试这样的事情。 PersonStudent各自定义了自己的GenerateRandomInstanceRandomizeProperties方法。 Student调用Person的{​​{1}}让基类随机化其知道的属性。 RandomizeProperties只会随机化Student类引入的属性。

注意:此问题通常由Abstract FactoryBuilder设计模式解决。下面的解决方案都不是那些。

Student

答案 2 :(得分:1)

您需要覆盖Student类中的GenerateRandomInstance()方法。目前正在调用Person中的基本方法。