2012-02-23 33 views
0
public class SomeClass<T> 
{ 
    public T DoSomething() 
    { 
     var obj = Activator.CreateInstance(this.GetType()); 
     // Do Things 
     return (T)obj; 
    } 
} 

public class DoStuff : SomeClass<DoStuff> 
{ 
} 

var ds = new DoStuff(); 
ds.DoSomething(); 

這個作品,但在這種情況下:C#反射投射到實例類型爲前變種O =(typeof運算(本))anotherobj

public abstract class AbstractStuff : SomeClass<AbstractStuff> 
{ 
} 

public class DoStuff : AbstractStuff 
{ 
} 

var ds = new DoStuff(); 
ds.DoSomething(); 

給我一個錯誤,不能實例化一個抽象一流的,我理解,我想做的事情是這樣的:

public class SomeClass<T> 
{ 
    public T DoSomething() 
    { 
     var obj = Activator.CreateInstance(this.GetType()); 
     // Do Things 
     return (my not know how to get this casting type)obj; 
    } 
} 

我tryed 回報(typeof運算(本))目標文件;

並沒有工作,一些想法? 感謝名單

SORRY:我忘了申報AbstractStuff抽象(修正)

+0

是不是失敗的CreateInstance? – kaj 2012-02-23 14:36:37

+0

不,CreateInstance正在工作,返回類型必須是(不)ç抽象,DoStuff不是抽象的,但T tyoe是AbstractStuffm我需要轉換爲此類型,thanx – manuellt 2012-02-23 14:38:55

+0

是AbstractStuff抽象的嗎? – 2012-02-23 14:43:09

回答

1

從你的問題考慮這個例子...

public class SomeClass<T> 
{ 
    public T DoSomething() 
    { 
     var obj = Activator.CreateInstance(this.GetType()); 
     // Do Things 
     return (T)obj; 
    } 
} 

...並在那裏你有

public abstract class AbstractStuff : SomeClass<AbstractStuff> { } 
public class DoStuff : AbstractStuff { } 

的情況下,如果用參數替換類型參數,你得到這個爲DoSomething()

public AbstractStuff DoSomething() 
{ 
    var obj = Activator.CreateInstance(this.GetType()); 
    // Do Things 
    return (AbstractStuff)obj; 
} 

現在讓我們重構了一下,爲了便於「調試」,並添加行號:

1 public AbstractStuff DoSomething() 
2 { 
3  var type = this.GetType(); 
4  var obj = Activator.CreateInstance(type); 
5  // Do Things 
6  return (AbstractStuff)obj; 
7 } 

如果你打電話的DoStuff一個實例這種方法,並在第4行打破,你會看到typeDoStuff;如果你在第6行中斷,你會看到obj的運行時類型也是DoStuff。當然,將該對象轉換爲AbstractStuff將會成功(並且甚至不需要轉換),因爲始終存在從任何引用類型到其基本類型的隱式引用轉換。

現在讓我們考慮一下您報告的錯誤消息:「無法實例化抽象類」。那是什麼告訴我們的?它說出於某種原因,當您調用Activator.CreateInstance時,您傳遞的是對AbstractStuff類型的引用。

這使得它看起來像你給我們的示例代碼是不準確的。 GetType()永遠不能返回抽象類型,因爲對象的運行時類型永遠不可能是抽象類型。換句話說,不可能有一個抽象類型的實例。

事實上,您所描述的行爲是,如果你有行預期...

var obj = Activator.CreateInstance(typeof(T)); 

...不是...

var obj = Activator.CreateInstance(this.GetType()); 

你確定這不是案件?

+0

你是對的,有些東西我錯過了,接下來我會發佈一個完整的問題代碼,謝謝。 – manuellt 2012-02-29 09:37:54

3

這對我的作品

public abstract class AbstractClass<T> where T : new() 
{ 
    public T DoSomething() 
    { 
     var obj = new T(); 

     // Do Things 

     return obj; 
    } 
} 

public class DoStuff : AbstractClass<DoStuff> 
{ 
} 

var ds = new DoStuff(); 
ds.DoSomething(); 

,因此不會改變原來的代碼是這樣的:

public T DoSomething() 
{ 
    var obj = Activator.CreateInstance(typeof(T)); 

    // Do Things 

    return (T)obj; 
} 

這樣我們就創建了非抽象派生類的實例,而不是抽象基類。

+0

和我..我認爲我們可能會錯過這個問題的重點,但.. – 2012-02-23 14:49:38

1

您無法將變量轉換爲編譯時未知的類型。想想你會如何調用該方法:

public class Foo : SomeAbstractClass<Bar> 
... 

Foo foo = new Foo(); 
??? newFoo = foo.DoSomething(); 

因爲Foo就繼承了SomeAbstractClass<Bar>你的第一個例子是將要返回Bar,但你似乎是希望能返回Foo代替。那隻會是可能如果Bar延伸Foo

你想要做更多這樣的事嗎?

void Main() 
{ 
    DoStuff doStuff = new DoStuff(); 
    DoStuff doStuff2 = doStuff.DoSomething(); 
} 

public abstract class SomeClass<T> 
    where T : SomeClass<T>, new() 
{ 
    public T DoSomething() 
    { 
     return new T(); 
    } 
} 

public class DoStuff : SomeClass<DoStuff> 
{ 

}