Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operator Overloading with C# Extension Methods

I'm attempting to use extension methods to add an operater overload to the C# StringBuilder class. Specifically, given StringBuilder sb, I'd like sb += "text" to become equivalent to sb.Append("text").

Here's the syntax for creating an extension method for StringBuilder:

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

It successfully adds the blah extension method to the StringBuilder.

Unfortunately, operator overloading does not seem to work:

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

Among other issues, the keyword this is not allowed in this context.

Are adding operator overloads via extension methods possible? If so, what's the proper way to go about it?

like image 469
Jude Allred Avatar asked Oct 05 '08 20:10

Jude Allred


People also ask

What is operator overloading with example in C?

Here, + is a binary operator that works on the operands num and 9 . When we overload the binary operator for user-defined types by using the code: obj3 = obj1 + obj2; The operator function is called using the obj1 object and obj2 is passed as an argument to the function.

Which operator is overloaded for C operation?

Input/Output Operators Overloading in C++ C++ is able to input and output the built-in data types using the stream extraction operator >> and the stream insertion operator <<. The stream insertion and stream extraction operators also can be overloaded to perform input and output for user-defined types like an object.

What is operator overloading with syntax?

Operator Overloading is the method by which we can change the function of some specific operators to do some different task. In the above syntax Return_Type is value type to be returned to another object, operator op is the function where the operator is a keyword and op is the operator to be overloaded.

What is meant by operator overloading?

Polymorphism: Polymorphism (or operator overloading) is a manner in which OO systems allow the same operator name or symbol to be used for multiple operations. That is, it allows the operator symbol or name to be bound to more than one implementation of the operator. A simple example of this is the “+” sign.


2 Answers

This is not currently possible, because extension methods must be in static classes, and static classes can't have operator overloads. But the feature is being discussed for some future release of C#. Mads talked a bit more about implementing it in this video from 2017.

On why it isn't currently implemented, Mads Torgersen, C# Language PM says:

...for the Orcas release we decided to take the cautious approach and add only regular extension methods, as opposed to extention properties, events, operators, static methods, etc etc. Regular extension methods were what we needed for LINQ, and they had a syntactically minimal design that could not be easily mimicked for some of the other member kinds.

We are becoming increasingly aware that other kinds of extension members could be useful, and so we will return to this issue after Orcas. No guarantees, though!

Further below in the same article:

I am sorry to report that we will not be doing this in the next release. We did take extension members very seriously in our plans, and spent a lot of effort trying to get them right, but in the end we couldn't get it smooth enough, and decided to give way to other interesting features.

This is still on our radar for future releases. What will help is if we get a good amount of compelling scenarios that can help drive the right design.

like image 61
Jacob Krall Avatar answered Sep 28 '22 01:09

Jacob Krall


If you control the places where you want to use this "extension operator" (which you normally do with extension methods anyway), you can do something like this:

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

The StringBuilderWrapper class declares an implicit conversion operator from a StringBuilder and declares the desired + operator. This way, a StringBuilder can be passed to ReceiveImportantMessage, which will be silently converted to a StringBuilderWrapper, where the + operator can be used.

To make this fact more transparent to callers, you can declare ReceiveImportantMessage as taking a StringBuilder and just use code like this:

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

Or, to use it inline where you're already using a StringBuilder, you can simply do this:

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

I created a post about using a similar approach to make IComparable more understandable.

like image 22
Jordão Avatar answered Sep 28 '22 00:09

Jordão