2015-06-12 204 views
1

我想設置一個方法,從數據庫中檢索數據,並根據數據在那裏它將創建和水合一個類與通用組件。C#泛型返回的泛型類型設置方法不在調用

public class MyObject<T> where T : BaseMyType 
{ 
    T MyTypedObject { get; set; } 
} 
public class MyType1 : BaseMyType 
{ 
    string Key { get; set; } 
} 
public class MyType2 : BaseMyType 
{ 
    Guid Id { get; set; } 
} 

public MyObject<T> MyMethod<T>() where T : BaseMyType 
{ 
    if(Situation1) 
     return new MyObject(MyType1); 
    else 
     return new MyObject(MyType2); 
} 

此代碼抱怨的MyObject <MyType1>不能轉換到MYOBJECT <Ť>。現在我需要像這樣使用它:

var myObject = MyMethod(); 

這個調用當然會抱怨它不能從使用中推斷出類型。我理解編譯器的錯誤信息,我只是不知道如何去做我需要的。

+3

鑑於這些在編譯時都不知道,所以根本不應該使用泛型。它不會幫助你;它只會阻礙你。 – Servy

+0

你有更好的方法建議嗎?除了數據加載以外,任何地方都可以滿足我們的需求,但我還沒有想出如何完成這一件事。 –

+1

爲什麼你需要泛型?接口可能已經足夠了 –

回答

1

它不能這樣做,但&hellip;讓我們假設的,我們可以想出一個辦法下列語句出現在你所希望的方式編譯了一下:

var myObject = MyMethod(); 

那麼什麼是代碼使用myObject去看起來像?在這種假設情況下,變量myObject有時會有MyType1類型,有時會有MyType2類型。請問使用myObject的代碼在意嗎?

如果所有代碼都會使用共享基類型的成員(即BaseMyType),那麼修復很容易。忘掉一般採用的方式:

public BaseMyType MyMethod() 
{ 
    if(Situation1) 
     return new MyType1(); 
    else 
     return new MyType2(); 
} 

如果確實關心的差異(即需要訪問要麼KeyId具體取決於所返回的類型),那麼即使你可以做不可能的事,調用代碼仍然需要根據變量Situation1有條件地處理各個場景。這意味着你把Situation1的支票放在了錯誤的地方。

相反,你的調用者應該看起來更像是這樣的:

if (Situation1) 
{ 
    MyType1 myObject = MyMethod1(); 

    // do situation 1 stuff 
} 
else 
{ 
    MyType2 myObject = MyMethod2(); 

    // do situation 2 stuff 
} 

凡執行原來的MyMethod()被分爲兩種方法,MyMethod1()MyMethod2(),對應於兩種情形。再次注意,作爲實施的一部分,完全缺乏泛型。它不被要求,並且不起作用。

甚至有可能您需要調用者的多態實現,即您不必多次檢查Situation1。但沒有a good, minimal, complete code example就不可能對這種可能性進行更徹底的評論。

+0

感謝彼得,這基本上是我結束了。關鍵在於重要的東西是基類中的虛擬方法,所以泛型的父類只是一個載體。所以我宣佈「開始」方法返回爲MyObject ,然後當它調用MyBase.Validate進入特定類型。序列化仍然序列化實際類型,所以一切都很好。你的帖子非常有幫助。 –