2013-07-31 116 views
3

我:靜態方法返回一個對象是一個包含類類型

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。 將一個人投給學生會給我一個錯誤

回答

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

當然,這如果指定的類型不包含一個合適的構造也將失敗。

+0

+1謝謝!人構造函數需要2個參數雖然...我應該提及,我不知道你會在哪裏發佈這個很好的答案;) –

+0

@TonoNam是參數將是相同的每個子類型的人或可能他們是不同的類型? –

+0

我正在編輯這將在那裏在不到1分鐘,感謝這麼多的幫助... –

1

您需要覆蓋Student類中的GenerateRandomInstance()方法。目前正在調用Person中的基礎方法。

+1

不能覆蓋靜態方法 –

+0

啊,對。錯過了。謝謝 –

2

嘗試這樣的事情。 PersonStudent各自定義它們自己的GenerateRandomInstanceRandomizeProperties方法。 Student調用PersonRandomizeProperties讓基類隨機化它所知道的屬性。然後Student將只會隨機分配由Student類引入的屬性。

注意:此問題通常由Abstract FactoryBuilder設計模式解決。以下解決方案既不是那些。

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 
    } 
} 
相關問題