簡體   English   中英

在C#中強制約束泛型類

[英]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>您可以根據您的要求使用CastOfType (無論您是要拋出還是忽略不兼容的匹配)。

如果它是.NET 4,它應該由於CoVariance功能自動工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM