2009-11-02 17 views
4

如果我有兩個類,並且已經定義了它們之間的顯式類型轉換,我應該不能將一個數組轉換爲另一個數組嗎?在C#中顯式對象數組類型轉換?

即。

using System; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Apple ted = new Apple() { Variety = Apple.EVariety.RedEllison }; 
      Orange bob = (Orange)ted; // explicit type conversion 

      Apple[] apples = new Apple[] { ted }; 
      Orange[] oranges = new Orange[1]; 

      //oranges = apples; // why is this illegal ? 

      // is this better ? 
      oranges = Array.ConvertAll<Apple, Orange>(apples, new Converter<Apple, Orange>(p => (Orange)p)); 
     } 

     class Apple 
     { 
      public enum EVariety { RedEllison, GrannySmith } 
      public EVariety Variety; 
     } 

     class Orange 
     { 
      enum EColour { Unknown, Red, Green } 
      EColour Colour; 

      public static explicit operator Orange(Apple apple) 
      { 
       Orange result = new Orange(); 
       result.Colour = apple.Variety == Apple.EVariety.RedEllison ? result.Colour = EColour.Red : result.Colour = EColour.Green; 
       return result; 
      } 
     } 
    } 
} 

感謝, 羅斯

回答

4

的轉化是唯一有效的,如果有在源和目標類型之間的引用轉換 - 換句話說,一個其中該陣列中的每個元件可以用作任一類型的,在不改變的數據。

從C#規範,第6.2.4節(顯式引用轉換):

顯式引用轉換 是:

...

  • 從陣列型S與元素類型SE到陣列類型T,其中元素類型爲 TE,前提條件是所有 均爲:
    • S和T僅在元素類型上有所不同。換句話說,S和T具有相同數量的維度。
    • SE和TE都是參考類型。
    • 從SE到TE存在明確的參考轉換。

在我看來,Array.ConvertAll肯定是去這裏的路,但你應該能夠使用類型推斷,使其更好:

oranges = Array.ConvertAll(apples, p => (Orange)p); 
+0

Ooohh! 我喜歡那樣的外觀。我不確定它是如何工作的(我使用intellisense來查找我的版本),但我確實喜歡它。現在我將走開並瞭解「類型推斷」。 謝謝。 –

0

我喜歡在System.Linq的擴展方法:

oranges = apples.Cast<Oranges>().ToArray(); 

編輯:

因爲演員不隱式轉換運營商合作,我會用select來代替:

oranges = apples.Select(x => (Oranges)x).ToArray(); 

與您的代碼不同的是,這會創建一個新數組,而您的數組是先創建數組,然後複製已轉換的引用。

+1

LINQ的.Cast真的會調用顯式的轉換操作符嗎? – dtb

+0

@dtb:據此:http://stackoverflow.com/questions/808725/why-does-a-linq-castt-operation-fail-when-i-have-an-implicit-cast-defined它不。我修復它。 –

2

埃裏克利珀寫了一本在他的博客上關於協變性和逆變性的系列貼子。他們在閱讀時會讓我的頭部受傷,但每次我都會稍微聰明些。這似乎最好的回答這個問題的帖子是

why-is-covariance-of-value-typed-arrays-inconsistent

我會建議瀏覽他的博客對相關的職位。

希望這有助於

0

,因爲編譯器不會把它自身的假設,你想要的是一個包含已經從蘋果橘子轉換一個新的數組這是非法的。

爲什麼不假定它可以做到這一點時,從蘋果到橙子的顯式轉換存在?

首先是因爲顯式意味着代碼應該專門請求它。例如,這仍然會失敗: -

anOrange = anApple; 

通過使用explicit關鍵字你說的轉換是可用的,但必須明確要求如下: -

anOrange = (Orange)anApple; 

其次即使implicit關鍵字被使用以便這是合法的: -

anOrange = anApple; 

這並不意味着對每個數組的整個數組也是如此。爲什麼這樣呢,設計人員可以看到數組的元素類型具有隱式轉換,因此技術上可以創建一個新數組並執行所有轉換?我不知道你會問他們。據猜測,這樣做的好處是最小的,尤其是因爲您已經發現了一個明確的單行選擇。開發,測試等成本(Eric Lippert的常用列表)成本相當高,我會想象。

+0

謝謝,我實際上先用隱式轉換編寫了這個例子(這不起作用),然後想到嘗試顯式版本 - 只有代碼仍試圖隱式轉換數組。糟糕! –