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

Personの代わりにを取得しStudentます。GenerateRandomInstancePerson ではなく Student を返すようにメソッドを修正するにはどうすればよいですか。人を生徒にキャストするとエラーが発生する

4

3 に答える 3

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

もちろん、指定された型に適切なコンストラクターが含まれていない場合、これも失敗します。

于 2013-07-31T20:20:20.390 に答える
2

このようなことを試してください。それぞれが独自の and メソッドを定義Personします。を呼び出して、基底クラスが認識しているプロパティをランダム化できるようにします。次に、クラスによって導入されたプロパティのみをランダム化します。StudentGenerateRandomInstanceRandomizePropertiesStudentPersonRandomizePropertiesStudentStudent

注: この問題は、多くの場合、Abstract FactoryまたはBuilderデザイン パターンによって解決されます。以下の解決策はそのどちらでもありません。

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 に答える