2010-05-20 57 views
3

我試圖做投列表爲IEnumerable,所以我可以確認的是不同的列表是不爲空或爲空:泛型列表<T>爲IEnumerable <object>

假設myList中是一個List < T>。然後在調用者的代碼,我想:

 Validator.VerifyNotNullOrEmpty(myList as IEnumerable<object>, 
            @"myList", 
            @"ClassName.MethodName"); 

的valdiating代碼將是:

 public static void VerifyNotNullOrEmpty(IEnumerable<object> theIEnumerable, 
             string theIEnumerableName, 
             string theVerifyingPosition) 
    { 
     string errMsg = theVerifyingPosition + " " + theIEnumerableName; 
     if (theIEnumerable == null) 
     { 
      errMsg += @" is null"; 
      Debug.Assert(false); 
      throw new ApplicationException(errMsg); 

     } 
     else if (theIEnumerable.Count() == 0) 
     { 
      errMsg += @" is empty"; 
      Debug.Assert(false); 
      throw new ApplicationException(errMsg); 

     } 
    } 

然而,這好好嘗試的工作。它編譯,但是數字是空的!爲什麼?

+0

做任何答案都有幫助嗎? – 2010-12-23 23:31:49

+0

@Dave - 哎呀。抱歉。很好的答案。接受Heinzi的,因爲它更關注爲什麼我的代碼不起作用,但你清楚地向我解釋了什麼應該工作。謝謝! – Avi 2011-01-04 02:00:39

回答

5

IEnumerable<object>不是IEnumerable<T>超類型,所以它不是的List<T>的超類型任一。請參閱question 2575363以簡要概述爲什麼會出現這種情況(這是關於Java的,但概念相同)。這個問題已經在C#4.0中得到了解決,順便說一句,其中的supports covariant generics

之所以沒有找到此錯誤,是因爲您使用了x as T,您應該使用普通演員表((T)x),請參閱question 2139798。由此產生的InvalidCastException會指出你的錯誤。 (事實上​​,如果類型的關係是正確的(即,如果IEnumerable<object>人的List<T>超類),你就不需要投都沒有。)

解決您的問題,讓你的方法通用的,所以它接受一個IEnumerable<T>而不是一個IEnumerable<object>,並完全跳過演員。

public static void VerifyNotNullOrEmpty<T>(IEnumerable<T> theIEnumerable, 
              string theIEnumerableName, 
              string theVerifyingPosition) { ... } 
+0

在這種情況下,您無法投射'(IEnumerable )myList'。 – Kobi 2010-05-20 12:39:40

+0

@Kobi:是的,正是我的觀點:如果你使用'(IEnumerable )myList',你會得到一個'InvalidCastException',並立即知道你使用的是錯誤的類型。如果你使用'myList作爲IEnumerable ',你還是想知道爲什麼結果是null(「myList null?或者演員失敗?」)。 – Heinzi 2010-05-20 12:43:09

+0

好的。我誤解了你;你似乎建議鑄造可能在這裏工作。 – Kobi 2010-05-20 12:53:55

4

假如你的目標至少框架3.0:

轉換爲通用IEnumerable<object>使用擴展:

var myEnumerable = myList.Cast<object>(); 

編輯: 反正我建議你改變你的方法來獲得純IEnumerable的像:

public static void VerifyNotNullOrEmpty(IEnumerable theIEnumerable, 
             string theIEnumerableName, 
             string theVerifyingPosition) 

,並且該方法檢查裏面如果空使用的foreach或theIEnumerable.Cast<object>().Count()

這樣你就不必每次都投來IEnumerable<object>

+0

不工作:-( 來電現在要求: Validator.VerifyNotNullOrEmpty(myList.Cast (),... 被叫仍收到了IEnumerable theIEnumerable爲空 – Avi 2010-05-20 12:19:01

+0

你肯定myList中不爲空 – digEmAll 2010-05-20 12:22:42

6

列表實現IEnumerable,所以你不必扮演他們,你只需要使它所以你的方法接受一個通用的參數,如所以:

public static void VerifyNotNullOrEmpty<T>(this IEnumerable<T> theIEnumerable, 
            string theIEnumerableName, 
            string theVerifyingPosition) 
{ 
    string errMsg = theVerifyingPosition + " " + theIEnumerableName; 
    if (theIEnumerable == null) 
    { 
     errMsg += @" is null"; 
     Debug.Assert(false); 
     throw new ApplicationException(errMsg); 

    } 
    else if (theIEnumerable.Count() == 0) 
    { 
     errMsg += @" is empty"; 
     Debug.Assert(false); 
     throw new ApplicationException(errMsg); 

    } 
} 

你應該只能夠與調用它:

var myList = new List<string> 
{ 
    "Test1", 
    "Test2" 
}; 

myList.VerifyNotNullOrEmpty("myList", "My position"); 

你也可以提高執行咯:

public static void VerifyNotNullOrEmpty<T>(this IEnumerable<T> items, 
            string name, 
            string verifyingPosition) 
{ 
    if (items== null) 
    { 
     Debug.Assert(false); 
     throw new NullReferenceException(string.Format("{0} {1} is null.", verifyingPosition, name)); 
    } 
    else if (!items.Any()) 
    { 
     Debug.Assert(false); 
     // you probably want to use a better (custom?) exception than this - EmptyEnumerableException or similar? 
     throw new ApplicationException(string.Format("{0} {1} is empty.", verifyingPosition, name)); 

    } 
} 
+0

這一次大概是?更好 - 它演示瞭如何編寫一個通用的擴展方法,當然,代碼很奇怪 - 在'errMsg'中添加文本在這裏是沒用的,但除此之外,還要注意'Count()可能會迭代整個集合,這可能不是我想要的,我更喜歡'.Any()'來檢查是否有任何項目可用,儘管這可能也有副作用 – Kobi 2010-05-20 12:22:23

+0

我同意errMsg,但我並不是真的想要改變他的實際執行時,只是改變簽名將做他所需要的... – 2010-05-20 12:25:35

+0

我的錯誤 - 錯誤消息進入新的異常,所以它做了一些事情。錯過了那一點:P。仍然有兩種不同類型的例外是優選的。 – Kobi 2010-05-20 12:28:14

相關問題