4

我有:

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();

我得到 aPerson而不是 a Student。如何修复该GenerateRandomInstance方法,使其返回一个学生而不是一个人。将一个人投射给学生会给我一个错误

4

3 回答 3

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;
}

当然,如果指定的类型不包含合适的构造函数,这也会失败。

于 2013-07-31T20:20:20.390 回答
2

尝试这样的事情。Person并且Student每个人都定义了自己的GenerateRandomInstance方法RandomizePropertiesStudent调用Person'sRandomizeProperties让基类随机化它知道的属性。Student然后只会随机化Student类引入的属性。

注意:这个问题通常由抽象工厂生成器设计模式解决。下面的解决方案都不是。

class Person
{
    public string Name { get; set; }

    public virtual void Speak()
    {
        Console.Write("Hello I am a person");
    }

    public static Person GenerateRandomInstance()
    {
        var o = new Person();
        RandomizeProperties(o);
        return o;
    }

    protected static void RandomizeProperties(Person o)
    {
        // randomize Person properties here
    }
}

class Student : Person
{
    public override void Speak()
    {
        Console.Write("Hello I am a student");
    }

    // note the use of the 'new' keyword
    new public static Student GenerateRandomInstance()
    {
        var o = new Student();
        RandomizeProperties(o);
        return o;
    }

    protected static void RandomizeProperties(Student o)
    {
        Person.RandomizeProperties(o);

        // randomize Student properties here
    }
}
于 2013-07-31T20:36:32.100 回答
1

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

于 2013-07-31T20:18:31.280 回答