is it possible to define an extension method that at the same time is an operator? I want for a fixed class add the possibility to use a known operator that actually can\'t
As shown in the other answers, it cannot be done directly. But what if you need it, say you want to improve StringBuilder like
void Main()
{
var log = (StringBuilder)"Hello ";
log += "World!";
log += "\nThis example shows how to extend StringBuilder";
log.ToString().Dump();
}
how can you achieve this (i.e. use +
operator instead of sb.Append(str);
) ?
Answer: In this case, you can't do it directly, but what you can do is:
Run it in DotNetFiddle
void Main()
{
var log = (StrBuilder)"Hello "; // same as: "Hello ".ToStrBuilder();
log += "World!";
log += "\nThis example shows how to extend StringBuilder";
log.ToString().Dump();
}
public static class Extensions
{
public static StrBuilder ToStrBuilder(this string str)
{
return new StrBuilder(str);
}
}
public class StrBuilder
{
private StringBuilder sb;
public StrBuilder()
{
sb = new StringBuilder();
}
public StrBuilder(string strB)
{
sb = new StringBuilder(strB);
}
public static implicit operator StrBuilder(string self)
{
return new StrBuilder(self);
}
public static StrBuilder operator +(StrBuilder sbA, string strB)
{
return sbA.Append(strB);
}
public StrBuilder Append(string strB)
{
sb.Append(strB);
return this;
}
public override string ToString()
{
return sb.ToString();
}
}
Note: You can't inherit from StringBuilder because it is a sealed class, but you can write a class that "boxes" a StringBuilder - which is, what is done here (thanks to IanNorton's answer regarding implicit conversion).
That is not possible in C#, but why not a standard extension method?
public static class StringExtensions {
public static string Increment(this string s) {
....
}
}
I think somestring.Increment()
is even more readable, as you're not confusing people who really dont expect to see ++
applied to a string.
No, you can't have an extension method which is also an operator. Extension methods can only be declared in static classes, which can't have instances and according to the C# spec,
User-defined operator declarations always require at least one of the parameters to be of the class or struct type that contains the operator declaration. [7.3.2]
Therefore, it is impossible for an extension method to also be an overloaded operator.
Additionally, you can't override System.String since it is a sealed class.
A clear example of where this would be useful is to be able to extend the TimeSpan class to include * and / operators.
This is what would ideally work...
public static class TimeSpanHelper
{
public static TimeSpan operator *(TimeSpan span, double factor)
{
return TimeSpan.FromMilliseconds(span.TotalMilliseconds * factor);
}
public static TimeSpan operator *(double factor, TimeSpan span) // * is commutative
{
return TimeSpan.FromMilliseconds(span.TotalMilliseconds * factor);
}
public static TimeSpan operator /(TimeSpan span, double sections)
{
return TimeSpan.FromMilliseconds(span.TotalMilliseconds / factor);
}
public static double operator /(TimeSpan span, TimeSpan period)
{
return span.TotalMilliseconds / period.TotalMilliseconds);
}
}
Currently this is not supported because Extension methods are defined in separate static class and static classes cannot have operator overloading definitions.
The string class is sealed in C#, so creating a string-derived class actually isn't possible.
That being said, an extension method will of course work just fine (as will a standard static method in a helper class) but it won't be an operator, just ordinarily-named method.