2013-01-19 64 views
2

我的目標是.NET框架的4.0版本。我寫了下面的簡單代碼:通過反射和隱式轉換創建通用列表

public class A 
{ 
    public A() 
    { 
    } 
} 

public class B 
{ 
    public B() 
    { 
    } 

    public static implicit operator A(B b) 
    { 
     return new A(); 
    } 
} 

然後,我創建了一個通用的清單:

var mylist = typeof(List<>).MakeGenericType(typeof(A)).GetConstructor(Type.EmptyTypes).Invoke(new object[]{}); 

當我想補充的B一個新的實例下面的代碼工作:

((IList<A>)mylist).Add(new B()); 

然而如果我運行下面的代碼,會拋出以下異常:

The value "B" is not of type "A" and cannot be used in this generic collection. 

參數名:價值

((IList)mylist).Add(new B()); 
+1

什麼是你的問題? –

+0

我該如何解決這個問題? –

回答

2

的隱式轉換的發生僅在第一Add作爲要添加B類型的對象到IList<A>。在第二種情況下,將其添加到非通用IList,這是對象的集合和隱式轉換不會發生和炸彈當對象實際上是添加到您的List<A>

即使失敗:

var mylist = new List<A>(); 
((IList<A>)mylist).Add(new B()); 
((IList)mylist).Add(new B()) 

你可以這樣做,但是:

((IList)mylist).Add((A)new B()); 
+0

Thanks.But我寫這個代碼進行測試。在真正的代碼中,我通過反射得到所有類型,並且我不能寫入Add((A)new B()); –

1

的問題是,當你投你的列表IList<A>並調用Add,編譯器(隱含)將強制轉換爲您B實例A。在第二種情況下,IList僅接受Add方法中的objectB是一個對象,所以它不會投射到A。因此,當該方法嘗試將其內部添加到基礎數據結構時,會引發異常。

你甚至可以通過這個代碼測試:

var fails = (A) (object) new B(); 

既然你問到如何解決這個問題(雖然我不認爲在這種情況下您鑄造類型IList的必要性),你可以只是在添加時將你的B明確地轉換爲A。例如:

mylist.Add((A) new B()); 
+0

Thanks.But我寫這個代碼進行測試。在真正的代碼中,我通過反射得到所有類型,並且我不能寫入Add((A)new B()); –

+0

@afshinalizadeh我明白了。 – Mir