[英]Casting constrained generic class in C#
很簡單,為什么這段代碼無法編譯?
public interface IWorld { }
public class Foo<T> where T : IWorld { }
public void Hello<T>(T t) where T : IWorld
{
Foo<IWorld> bar1 = new Foo<T>(); //fails implicit cast
Foo<IWorld> bar2 = (Foo<IWorld>)new Foo<T>(); //fails explicit cast
}
由於每個T
實現了IWorld
,因此Foo<T>
每個實例都應該與Foo<IWorld>
匹配。 為什么不? 有沒有辦法解決? 我真的不想借助於泛型來實現這一目標。
T : IWorld
意味着T已經實施了IWorld,並不意味着它只實現了IWorld,而且確實是IWorld。 它也可能已經實現了其他接口。
但是,C#在其更高版本中支持此演員。 請參閱http://msdn.microsoft.com/en-us/library/dd799517.aspx (泛型中的協方差和反演)
您可以先轉換為對象
Foo<IWorld> bar2 = (Foo<IWorld>)(object)new Foo<T>();
一個更簡單的反對意見 - 想象一下,而不是Foo
,這就是List
。
將List<T>
轉換為List<IWorld>
,我現在可以將一些其他 IWorld
實現對象(比如T2
類型)添加到一個列表中,該列表僅限於包含T
類型的對象。 這不應該是有效的。
所以回到你的Foo
對象 - 如果它包含任何期望用類型T
對象調用的方法,我現在可以用任何實現IWorld
對象來調用它們 - 即使(想象一下Foo
的另一個類型約束)該對象也不會是Foo
的合格類型。
我在評論中的觀點re:值類型。 同樣,如果我們按照List<T>
討論,這可能會更容易 - 值類型的List<T>
包含沒有裝箱的值類型。 如果您需要具有這些相同值的List<IWorld>
,則必須在將每個值添加到列表之前將其裝箱 。
以下是什么問題
Foo<IWorld> bar1 = new Foo<IWorld>();
你想要實現什么目標?
如果你需要傳遞IWorld
實例,你可以安全地傳遞T
,但在你的代碼中並非如此。
編輯 (根據評論)
要轉換為Foo<Array of something>
您可以根據您的要求使用Cast或OfType (無論您是要拋出還是忽略不兼容的匹配)。
如果它是.NET 4,它應該由於CoVariance功能自動工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.