2011-08-17 39 views
5

我想擴展.NET的內置Color結構來添加新運算符,如+-
我會用他們喜歡的:在C#中擴展現有結構以添加運算符

Color c1 = Color.FromName("Red"); 
Color c2 = Color.FromName("Blue"); 
Color result = c2 - c1; 

這可能嗎?如果是的話,怎麼樣?

+1

我不確定這是否可以做,但我很好奇,'紅藍'的結果會是什麼? – n8wrl

+1

@ n8wrl:確實很奇怪,但我希望有一個'-'可以去掉其他顏色的RGB值。 – Yuck

+2

@ n8wrl無論紫色的反義詞是什麼,大概是:-) –

回答

4

有沒有辦法與內置的運營商做到這一點。

你可以寫,雖然擴展方法,以一種假的吧:

public static class Extensions 
{ 
    public static Color Substract(this Color color, Color theOtherColor) 
    { 
     //perform magic here! 
     //be sure to return something or this won't compile 
    } 
} 

Color c1 = Color.FromName("Red"); 
Color c2 = Color.FromName("Blue"); 
Color result = c2.Subtract(c1); 
+0

你的語法在'Color'上定義擴展方法是錯誤的。必須是'靜態'方法的靜態類。 – Yuck

+0

我只是注意到我錯過了'靜態'修飾符。 – asawyer

+1

@asawyer,刪除'return null'。 「顏色」是一種價值型。 –

1
+0

我知道擴展方法,但只是想知道使用操作符的可能性。 –

+0

比@iandotkelly回答。 –

2

C#中的結構和類共享很多相似之處,然而其中一個區別是你不能繼承一個結構。您可以使用擴展方法來實現Add()或Subtract()方法,但不能在擴展方法中編寫運算符重載。

如果我是你,我真的想擴展現有的結構的功能,我會將結構包裝在我自己的類中。

+0

+1這看起來像是一個奇怪的地方使用擴展方法。 – Yuck

3

正如其他人的建議,你可以去任何擴展方法方式或Decorator模式的方式。

但是,考慮到Color具有相當數量的屬性和方法,所以將它們全部從decorator類重定向到包裝的Color結構將意味着需要編寫大量樣板。如果你走這條路,但是,你確實可以從你的類的顏色和周圍的其他方式確定經營者,甚至隱式轉換(這樣你可以更交替使用它們),像這樣:

public class MyColor { 
    public System.Drawing.Color val; 

    public MyColor(System.Drawing.Color color) 
    { 
     this.val = color; 
    } 

    public static MyColor AliceBlue 
    { 
     get { 
      return new MyColor(System.Drawing.Color.AliceBlue); 
     } 
    } 

    public override string ToString() 
    { 
     return val.ToString(); 
    } 
    // .... and so on.... 

    // User-defined conversion from MyColor to Color 
    public static implicit operator System.Drawing.Color(MyColor c) 
    { 
     return c.val; 
    } 
    // User-defined conversion from Color to MyColor 
    public static implicit operator MyColor(System.Drawing.Color c) 
    { 
     return new MyColor(c); 
    } 
} 

測試:

MyColor c = System.Drawing.Color.AliceBlue; // assigning a Color to a MyColor 
              // thanks to the implicit conversion 
Console.WriteLine(c.ToString()); // writes "Color [AliceBlue]" 
+0

這是一個非常好的參考例子,但是(在我目前的情況下)它只會讓一切變得更加困難。不過,隱式操作符在編寫代碼時真正清理了這些事情。 –

+1

@canpoyrazoğlu我同意。我個人會在你的場景中使用擴展名:我的例子更多的是爲了向你展示如何使用顏色等「大」結構來構建另一種方式。 –

0

如果你不能擴展某些東西,你也可以創建一個包裝類或結構體。在許多情況下,合成實際上比擴展更強大和更靈活。

它允許多重繼承,你可以輕鬆地升級/包裝已有對象等

我並不是說這是最好的回答這個問題,但肯定是值得考慮的。 :)