代码之家  ›  专栏  ›  技术社区  ›  Jude Allred

使用C#扩展方法的运算符重载

  •  158
  • Jude Allred  · 技术社区  · 18 年前

    我正在尝试使用扩展方法将运算符重载添加到C# StringBuilder 班具体来说 字符串拼接 sb ,我想要 sb += "text" 等同于 sb.Append("text") .

    下面是为创建扩展方法的语法 :

    public static class sbExtensions
    {
        public static StringBuilder blah(this StringBuilder sb)
        {
            return sb;
        }
    } 
    

    它成功地添加了 blah 扩展方法 字符串拼接 .

    不幸的是,运算符重载似乎不起作用:

    public static class sbExtensions
    {
        public static StringBuilder operator +(this StringBuilder sb, string s)
        {
            return sb.Append(s);
        }
    } 
    

    在其他问题中,关键字 this 在此上下文中不允许。

    是否可以通过扩展方法添加运算符重载?如果是,正确的方法是什么?

    6 回复  |  直到 14 年前
        1
  •  157
  •   Neuron MonoThreaded    6 年前

    这在当前是不可能的,因为扩展方法必须在静态类中,并且静态类不能有运算符重载。但是 feature is being discussed for some future release of C# in this video from 2017 .

    C#Language项目经理马德斯·托格森(Mads Torgersen)在谈到目前为何没有实施时说:

    采取谨慎的态度,增加 仅常规扩展方法,如 与延展性相反, 语法上最小的设计 其他成员种类的。

    我们越来越意识到这一点 其他类型的扩展成员 可能有用,所以我们会回来 不过,保证!

    在同一条中进一步说明:

    我们将在下一版本中这样做。我们 你很喜欢推广员吗 为了得到它们,我们付出了很多努力 是的,但最后我们没能 它足够光滑,并决定放弃 其他有趣的功能。

    这仍在我们未来的雷达上 大量引人注目的场景 这有助于推动正确的设计。

        2
  •  60
  •   Jordão    14 年前

    如果控制要使用此“扩展运算符”(通常使用扩展方法)的位置,可以执行以下操作:

    class Program {
    
      static void Main(string[] args) {
        StringBuilder sb = new StringBuilder();
        ReceiveImportantMessage(sb);
        Console.WriteLine(sb.ToString());
      }
    
      // the important thing is to use StringBuilderWrapper!
      private static void ReceiveImportantMessage(StringBuilderWrapper sb) {
        sb += "Hello World!";
      }
    
    }
    
    public class StringBuilderWrapper {
    
      public StringBuilderWrapper(StringBuilder sb) { StringBuilder = sb; }
      public StringBuilder StringBuilder { get; private set; }
    
      public static implicit operator StringBuilderWrapper(StringBuilder sb) {
        return new StringBuilderWrapper(sb);
      }
    
      public static StringBuilderWrapper operator +(StringBuilderWrapper sbw, string s) { 
          sbw.StringBuilder.Append(s);
          return sbw;
      }
    
    } 
    

    这个 StringBuilderWrapper 类声明 implicit conversion operator StringBuilder 声明所需的 + 操作人员这边,a 字符串拼接 可以传递给 ReceiveImportantMessage ,将以静默方式转换为 架线机 +

    要使此事实对调用方更加透明,可以声明 作为一个 字符串拼接

      private static void ReceiveImportantMessage(StringBuilder sb) {
        StringBuilderWrapper sbw = sb;
        sbw += "Hello World!";
      }
    

    或者,在已经使用 字符串拼接 ,您只需执行以下操作:

     StringBuilder sb = new StringBuilder();
     StringBuilderWrapper sbw = sb;
     sbw += "Hello World!";
     Console.WriteLine(sb.ToString());
    

    a post 关于使用类似的方法来制作 IComparable

        3
  •  8
  •   abatishchev Karl Johan    16 年前

    http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=168224

    建议它可能会出现在未来的版本中,但当前版本未实现。

        4
  •  2
  •   Neuron MonoThreaded    6 年前

    哈!我在查找“扩展运算符重载”时也有同样的愿望,例如 sb += (thing) .

    sb.AppendLine 和 sb.AppendFormat

    public static class SomeExtensions
    {
        public static void Line(this StringBuilder sb, string format, params object[] args)
        {
            string s = String.Format(format + "\n", args);
            sb.Append(s);
        }
    }
    

    所以,,

    sb.Line("the first thing is {0}", first);
    sb.Line("the second thing is {0}", second);
    

    这不是一个笼统的答案,但可能会引起未来研究此类问题的求职者的兴趣。

        5
  •  1
  •   Chuck Rostance    14 年前

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;    
    
    namespace Whatever.Test
    {
        public static class Extensions
        {
            public static int Compare(this MyObject t1, MyObject t2)
            {
                if(t1.SomeValueField < t2.SomeValueField )
                    return -1;
                else if (t1.SomeValueField > t2.SomeValueField )
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            }
    
            public static MyObject Add(this MyObject t1, MyObject t2)
            {
                var newObject = new MyObject();
                //do something  
                return newObject;
    
            }
    
            public static MyObject Subtract(this MyObject t1, MyObject t2)
            {
                var newObject= new MyObject();
                //do something
                return newObject;    
            }
        }
    
    
    }
    
        6
  •  0
  •   will motil    9 年前

    我在这里的某个地方贴了一个帖子,但是它毫无价值。

    顺便提一下 所有数值转换都会在字符串生成器中创建需要修复的垃圾。我必须为那些有用的东西写一个包装,我使用它。这值得一读。