2011-11-15 192 views
1

我有一個聲明,像這樣的功能:函數聲明

public static string MultiWhereToString(List<WhereCondition<T>> whereConditions) 

我想傳遞一個叫whereAnd變量,它是delcared像這樣:

private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>(); 

WhereAndConditionWhereCondition的子類。它宣稱,像這樣:

public class WhereAndCondition<T> : WhereCondition<T>, IConditional where T : DatabaseObject 

我的問題是,如果我嘗試執行以下代碼:

private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>(); 
MultiWhereToString(whereAnd); 

我收到以下錯誤:

Error 3 Argument 1: cannot convert from 'System.Collections.Generic.List<BrainStorm.WhereAndCondition<T>>' to 'System.Collections.Generic.List<BrainStorm.WhereCondition<T>>' 

爲什麼任何想法?我認爲它與WhereCondition類的泛型有關。

+2

你可以'公共靜態字符串MultiWhereToString(IList > whereConditions)'? – Joe

+1

[在C#中,是否可以將列表轉換爲列表?](http://stackoverflow.com/questions/1777800/in-c-is-it-possible-to-cast-a-listchild-to -listparent) –

+2

如果您要傳遞IEnumerable而不是List,則可以利用協方差特徵。 http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx – spender

回答

2

我會建議使用的接口:

public static string MultiWhereToString(IEnumerable<ICondition<T>> whereConditions) 

調用此方法時,這將讓你有更多的自由。

2

鑑於:

class A {} 
class A : B {} 

List<B>一個目的是List<A>一個實例。所以你不能投到List<WhereCondition>。你可以使用:

MultiWhereToString(whereAnd.OfType<WhereCondition>().ToList()); 

(也有可能是涉及inout方差註釋的解決方案,但我並不十分熟悉。)

2

你的函數定義爲採取WhereCondition列表,但你傳遞一個WhereAndCondition列表:

MultiWhereToString(List<WhereCondition<T>> whereConditions)

private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>(); 
MultiWhereToString(whereAnd); 

李st差異在.NET 4中受到了有限的支持。請參閱this question

+0

原因在於演員陣容根本不是類型安全 - 數據丟失在哪裏? – millimoose

+0

@Inerdia - 我意識到,只要我張貼;我有一個大腦放屁,想把父母變成孩子,而不是相反。鏈接編輯比我可以輕鬆提供更好的解釋。而且我意識到'數據丟失'並不是真正的正確術語。我的語言技能是垃圾。 –

2

泛型必須在編譯時明確知道,因爲它們是生成的。

爲什麼不使用:

private List<WhereCondition<T>> whereAnd = new List<WhereCondition<T>>(); 

所以,你仍然可以添加WhereAndCondition對象whereAnd

2

您可以將MultiWhereToString方法中的整個WhereCondition<T>替換爲另一種限制爲WhereCondition<T>的通用類型。

替換:

public static string MultiWhereToString(List<WhereCondition<T>> whereConditions) 

有了:

public static string MultiWhereToString<TType>(List<TType> whereConditions) where TType: WhereCondition<T> 

或者交替變化:

private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>(); 

到:

private List<WhereCondition<T>> whereAnd = new List<WhereCondition<T>>(); 

讓繼承爲你休息。

2

這似乎是一個協變/逆變問題。

簡體到這一點:

public class WhereCondition 
    { 
    } 

    public class WhereAndCondition : WhereCondition 
    { 
    } 

    public class blah 
    { 
     public static void Blah() 
     { 
      List<WhereAndCondition> whereAnd = new List<WhereAndCondition>(); 
      MultiWhereToString(whereAnd); 
     } 

     public static string MultiWhereToString(List<WhereCondition> whereConditions) 
     { 
      return null; 
     } 
    } 

它不會工作,因爲WhereAndConditions列表不能轉換到列表WhereConditions的:

想象一下這種方式。你有一個長頸鹿列表,方法是要求一個動物列表。

不知道他們會做的名單動物(如嘗試加入馬)的類型是不相容的,但如果你將其更改爲這樣的事情:

 public static string MultiWhereToString(IEnumerable<WhereCondition> whereConditions) 
     { 
      return null; 
     } 

然後方差可以踢在,並給你你想要的。