【问题标题】:Extend an existing struct in C# to add operators在 C# 中扩展现有结构以添加运算符
【发布时间】:2011-10-29 00:44:46
【问题描述】:

我想扩展 .NET 的内置 Color 结构以添加新的运算符,例如 +-
我会像这样使用它们:

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

有可能吗?如果是,怎么做?

【问题讨论】:

  • 我不确定这是否可以做到,但我很好奇'red - blue'的结果会是什么?
  • @n8wrl:确实很奇怪,但我希望- 可以从其他颜色中删除该颜色的任何 RGB 值。
  • @n8wrl 不管紫色的反面是什么,大概:-)
  • 它将对常规的 24 位颜色进行逐个​​减法,例如减去红色、绿色和蓝色。这只是一个简单的演示示例,显然在此示例中结果将是红色(因为我会将负值转换为 0),但我不会使用它来“从蓝色中减去红色”:)
  • 好的,大家别忘了Color,以免造成进一步的混乱。毕竟这是一个 C# 问题 :) 判断是否可以使用运算符扩展现有结构..

标签: c# .net struct operator-keyword


【解决方案1】:

这是一个老问题,但既然它出现在我的 DuckDuckGoSearch 上,我认为应该回答它。

可以在 C# 中执行此操作。无论如何,现在你可以了。可能不是 9 年前被问到的时候。

有关您需要的所有信息,请参阅此文档: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/operator-overloading

在结构内部,它看起来像这样:

public static Fraction operator -(Fraction a, Fraction b)
        => a + (-b);

【讨论】:

    【解决方案2】:

    如果你不能扩展某些东西,你也可以创建一个包装类或结构。在许多情况下,组合实际上比扩展更强大、更灵活。

    它允许多重继承,您可以轻松升级/包装现有对象等。

    我并不是说这是这个问题的最佳答案,但肯定是值得考虑的。 :)

    【讨论】:

      【解决方案3】:

      正如其他人所建议的,您可以采用扩展方法方式或装饰器模式方式。

      但是,考虑到 Color 具有相当数量的属性和方法,因此将它们全部从装饰器类重定向到包装的 Color 结构将意味着编写大量样板文件。但是,如果你走这条路,你确实可以定义运算符,甚至可以定义从你的类到 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]"
      

      【讨论】:

      • 这是一个非常好的参考示例,但(在我目前的情况下)它只会让一切变得更难。虽然代码不错,但隐式运算符确实在编写代码时清理了这些东西。
      • @can poyrazoğlu 我同意。我会亲自在您的场景中使用扩展:我的示例更多地是为了向您展示另一种方式使用像 Color 这样的“大”结构会变得多么混乱......
      【解决方案4】:

      C# 中的结构和类有很多相似之处,但其中一个区别是不能对结构进行子类化。您可以使用扩展方法来实现 Add() 或 Subtract() 方法,但不能在扩展方法中编写运算符重载。

      如果我是你并且我真的想像这样扩展现有结构的功能,我会将结构包装在我自己的类中。

      【讨论】:

      • +1 使用扩展方法看起来确实是个奇怪的地方。
      【解决方案5】:

      我会说这些已经存在,您是在谈论重新定义它们吗?这些是对颜色的 alpha 和 RGB 的操作。见下文:

      http://msdn.microsoft.com/en-us/library/system.windows.media.color.op_subtraction.aspx

      http://msdn.microsoft.com/en-us/library/system.windows.media.color.op_addition.aspx

      【讨论】:

      • OP 询问的Color 对象存在于System.Drawing 命名空间中。不是你引用的那个。
      【解决方案6】:

      使用内置运算符无法做到这一点。

      你可以写一个扩展方法来伪装它:

      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);
      

      【讨论】:

      • 您在Color 上定义扩展方法的语法错误。必须是带有 static 方法的 static 类。
      • 我刚刚注意到我缺少static 修饰符。
      • @asawyer,删除 return nullColor 这是一个值类型。
      • @Kirill 好吧,这只是为了表达这个想法,因此是关于魔法的评论。
      【解决方案7】:

      【讨论】:

      • 我知道扩展方法,但只是想知道使用运算符的可能性。
      • 不如看看@iandotkelly 的回答。
      猜你喜欢
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 2020-12-20
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多