2011-04-08 69 views
1

我一直在與此爭鬥一段時間,所以任何幫助將不勝感激。這是我在C#.NET 4.0中遇到的場景。C#.NET 4.0拋出異常的泛型協方差問題

public interface ITableBusinessLogicLayerIn<in TTableRecord> : IBusinessLogicLayer 
    where TTableRecord : ITableRecord 
{ 
// No definition 
} 

public interface ITableBusinessLogicLayerOut<out TTableRecord> : IBusinessLogicLayer 
    where TTableRecord : ITableRecord 
{ 
// No definition 
} 

我有一個對象,它實現了兩個接口。代碼編譯正常。但在運行時,我能夠施放此對象如下:

(ITableBusinessLogicLayerOut<ITableRecord>)obj 

但不是這樣的:

(ITableBusinessLogicLayerIn<ITableRecord>)obj 

這是非常令人困惑,我不知道我在做什麼錯。有人請給我指出正確的方向。謝謝!

+0

我確定這與「in」泛型參數主要用於lambdas和方法而不用於類的事實有關,因爲它們都是關於傳遞值「in」的。雖然這是我的一切。 :) – 2011-04-08 05:08:47

回答

3

逆變(in)允許您將具有較少特定類型的類型參數的對象轉換爲更具體的類型之一。例如,不能將對象傳遞給期望字符串的類型,因此您不能將需要字符串的類型轉換爲期望對象的類型。在這裏看到更多的信息:http://msdn.microsoft.com/en-us/library/ee207183%28d=lightweight%29.aspx

考慮下面的例子:

class MyTableRecord : ITableRecord { } 
ITableBusinessLogicLayerIn<ITableRecord> inA; 
ITableBusinessLogicLayerIn<MyTableRecord> inB; 
ITableBusinessLogicLayerOut<ITableRecord> outA; 
ITableBusinessLogicLayerOut<MyTableRecord> outB; 

您可以分配到inBinA,而不是相反。您可以將outA指定爲outB,但不能相反。

+0

嗨Talljoe。我需要使用通用接口ITableBusinessLogicLayerIn,以便我可以添加,更新任何類型的ITableRecord對象,即UserRecord,RoleRecord,MenuRecord等。我將如何實現這一目標? – c0D3l0g1c 2011-04-08 05:21:47

+0

對於你在做什麼你可能不需要差異。一個簡單的通用將起作用。只有當您希望能夠將一種類型用於另一種類型的情況時,方差纔是可能的,因爲這兩種類型都是相同的通用基礎,但具有不同的類型參數(如在某些需要IEnumerable 的地方使用IEnumerable )。你通常必須選擇一個方向或另一個方向,你不能同時做(或者你基本上以不變爲結果)。 – Talljoe 2011-04-08 05:39:20

+0

感謝您的回答和建議。非常感激。 – c0D3l0g1c 2011-04-08 05:44:10