2010-07-24 88 views
4

我有2個基類FirstBase和SecondBase。我還有2個從它們派生的類,DerivedFirst和DerivedSecode,它們都具有幾乎相同的屬性。源代碼如下所示。如何將X列表轉換爲C#中的Y列表?

public abstract class FirstBase 
{ 
    //some method 
} 

public abstract class SecondBase 
{ 
    //some method 
} 

public class DerivedFirst : FirstBase 
{ 
    //override methods of its parent 

    public static implicit operator DerivedFirst(DerivedSecond second) 
    { 
     //doing some logic here 
    } 
} 

public class DerivedSecond : SecondBase 
{ 
    //override methods of its parent 

    public static implicit operator DerivedSecond(DerivedFirst first) 
    { 
     //doing some logic here 
    } 
} 

從這段代碼我可以創建DerivedFirst的實例並分配給DerivedSecond沒有任何問題。但是,當我嘗試將它們的列表轉換爲下面的代碼時,它沒有結果。

List<DerivedFirst> firstList; 
List<DerivedSecond> secondList; 

//doing some operation here 

List<DerivedSecod> test = firstList.Cast<DerivedSecond>(); // don't have any output here. 

如何將firstList轉換爲List()?

回答

4

用戶定義的隱式轉換僅在編譯時考慮,而不是在運行時(source)。您可以使用Select來代替:

List<DerivedSecond> foo = firstList.Select(x => (DerivedSecond)x).ToList(); 
+0

我已經嘗試這種方法,但是當我調試到foo是節目則「」 {「無法投類型的對象DerivedFirst爲鍵入‘DerivedSecond’。」} – Anonymous 2010-07-24 10:08:36

+0

@Ekkapop:我已經更新了我的答案。 – 2010-07-24 10:46:17

2

您的期望行爲不起作用。 static implicit operator只不過是編寫代碼的一種奇特方式。 DerivedFirst不能真正被轉換成DerivedSecond。

FirstList.Cast<DerivedSecond>的調用起作用,因爲LINQ在訪問其項目時在輸入列表上流動。只要您訪問生成的IEnumerable<DerivedSecond>中的任何物品,就會獲得InvalidCastException

試試這個Visual Studio的測試代碼,看看我的意思:

[TestClass] 
    public class UnitTest1 { 
     class DerivedA { 
     public static implicit operator DerivedA(DerivedB b) { 
      return new DerivedA(); 
     } 
     } 
     class DerivedB { 
     public static implicit operator DerivedB(DerivedA a) { 
      return new DerivedB(); 
     } 
     } 

     [TestMethod] 
     public void TestMethod1() { 
     IList<DerivedA> lista = new List<DerivedA> { 
      new DerivedA() 
     }; 
     var casted = lista.Cast<DerivedB>(); 

     try { 
      DerivedB b = casted.First(); 
      Assert.Fail(); 
     } catch (InvalidCastException) { 
      // exception will be thrown 
     } 
     } 
    } 

編輯: 以「鑄造」的對象是使用「選擇」方法的唯一解決辦法:

var casted = lista.Select(a => (DerivedB)a); 
0

您剛纔談到了差異。 C#實際上在.NET 4.0中引入了協變量。因此,如果您使用C#4.0,則可以在列表中使用out運算符輕鬆完成此操作。

檢查我的文章

http://www.abhisheksur.com/2010/06/c-40-features.html

我希望這會幫助你。

否則,您可以使用Loop來轉換每個單獨的對象以創建該類型的單獨列表。

相關問題