2011-11-09 63 views
1

如果我有一個對象,它看起來像:對象[]列出<Interface>返回null

class Person : IProxy 
{ 
    // Properties 
} 

而且我有一個返回object這實際上是一個List<Person>的方法:

object GetList() 
{ 
    List<Person> people = new List<Person>(); 

    person.Add(new Person()); 
    person.Add(new Person()); 

    return people; 
} 

爲什麼下面的代碼是否會導致null?

var obj = GetList() as List<IProxy>; 

但下面的代碼返回一個列表:

var obj = GetList() as List<Person>; 

在Visual Studio的手錶面板,我喜歡的類型被報告爲:

object {System.Collections.Generic.List<Person>} 
+2

一個'名單'是_not_一個'名單'不管人對IProxy關係。在stackoverflow上有很多關於這個問題的問題(vs vs協方差)。簡而言之,您可以這樣做:'(GetList()as List ).Cast ();' – Rob

回答

5

一個List<Person>List<IProxy>是兩個不同的將一個轉換爲另一個的類型可能會產生空值。

GetList().OfType<IProxy>() 

會做你想做的。您還可以使用

GetList().Cast<IProxy>() 

個人而言,我更喜歡OfType因爲當集合包含異類類型

Covariance and Contravariance FAQ可以回答更多的問題,你不拋出異常。

+1

正如問題的評論中所建議的那樣,最好使用Cast ()而不是OfType ()。實際上,OfType ()會過濾掉所有非IProxy類型的元素。在這種情況下,結果是一樣的,但不是一般的。 此外,如果obj需要確實是一個列表,則正確的表達式是GetList()。Cast ().ToList() – Teudimundo

+0

@Teudimundo ..Thanks ...我已經編輯了我的答案和理性 –

+0

謝謝。我會給出這個問題並閱讀FAQ – Darbio

1

因爲List<People>是與List<IProxy>不同的類型。想象一下你有class Cat : IProxy。如果您可以將List<People>轉換爲List<IProxy>,則可以將Cat添加到它,我假設您不想要。這裏缺少的是通用的逆轉,例如,在java中,您可以合法地將您的列表轉換爲List<? extends IProxy>,這將允許您從列表中讀取IProxy對象,但不會寫入任何內容。

+0

謝謝西蒙。其實我確實需要添加一個IProxy項目列表,這些項目可能有不同的類型。上面的代碼是我爲了測試邏輯而做的抽象(並使問題更容易)。 – Darbio

+0

如果您需要合併'List '的多個實例,其中'T'不一樣,但始終實現'IProxy',則可以創建一個列表'代理=新列表();'並調用'代理。的AddRange(人); proxies.AddRange(otherProxyTypeList);'等等。 – phoog

-2

爲什麼返回類型爲GetList()object?指定List<Person>IList<Person>會更有意義。這樣,你就不必在調用方法之後進行投射。

如果你想從你的方法List<IProxy>,你可以這樣做:

List<IProxy> GetList() 
{ 
    List<IProxy> people = new List<IProxy>(); 

    people.Add(new Person()); 
    people.Add(new Person()); 

    return people; 
} 

然後

var obj = GetList(); 
+1

雖然這是真的,但它不回答問題。 – Amy

+0

這是真的,但我正在使用反射在運行時返回對象的所有屬性,並且該值作爲對象返回,而不是強類型List。 – Darbio

+0

@JD從您發佈的代碼示例中看不出來,它顯示了一種創建列表並將其作爲對象返回的方法。 – phoog