用C#扩展方法重载操作符
我试图使用扩展方法将操作符重载添加到C# StringBuilder
类。 具体来说,给定StringBuilder
sb
,我希望sb += "text"
等同于sb.Append("text")
。
以下是为StringBuilder
创建扩展方法的语法:
public static class sbExtensions
{
public static StringBuilder blah(this StringBuilder sb)
{
return sb;
}
}
它成功地增加了blah
的扩展方法的StringBuilder
。
不幸的是,运算符重载似乎不起作用:
public static class sbExtensions
{
public static StringBuilder operator +(this StringBuilder sb, string s)
{
return sb.Append(s);
}
}
在其他问题中,关键字this
在这种情况下是不允许的。
是否可以通过扩展方法添加运算符重载? 如果是这样,那么有什么正确的方法呢?
目前这是不可能的,因为扩展方法必须在静态类中,静态类不能有运算符重载。
Mads Torgersen,C#Language PM说:
...对于Orcas版本,我们决定采取谨慎的方法,只添加常规的扩展方法,而不是扩展属性,事件,运算符,静态方法等。定期扩展方法是我们需要的LINQ,他们有一个语法最小化的设计,不能轻易模仿其他一些成员类型。
我们越来越意识到其他类型的扩展成员可能是有用的,所以我们将在Orcas之后回到这个问题。 不过没有保证!
编辑:
我刚刚注意到,Mads在同一篇文章中写道:
我很抱歉地报告说,我们不会在下一个版本中这样做。 在我们的计划中,我们确实非常认真地对待推广成员,并花费了很大的努力试图让它们正确,但最终我们无法获得足够的平滑,并决定让位给其他有趣的功能。
这仍然在我们的未来版本上。 如果我们获得大量有吸引力的场景,可以帮助推动正确的设计,那将会有所帮助。
该功能目前位于C#8.0的桌面上(可能)。 Mads在这里谈论更多关于实施它的内容。
如果你控制了你想使用这个“扩展操作符”的地方(你通常使用扩展方法),你可以这样做:
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
类从声明的隐式转换运算符StringBuilder
并声明所需的+
运算符。 这样,一个StringBuilder
可以传递给ReceiveImportantMessage
,它将被悄悄地转换为一个StringBuilderWrapper
,在那里可以使用+
操作符。
为了让调用者更加透明,可以将ReceiveImportantMessage
声明为一个StringBuilder
并使用如下代码:
private static void ReceiveImportantMessage(StringBuilder sb) {
StringBuilderWrapper sbw = sb;
sbw += "Hello World!";
}
或者,要在您已经使用StringBuilder
下使用它,您可以简单地执行此操作:
StringBuilder sb = new StringBuilder();
StringBuilderWrapper sbw = sb;
sbw += "Hello World!";
Console.WriteLine(sb.ToString());
我创建了一篇关于使用类似方法使IComparable
更易于理解的文章。
看起来目前这是不可能的 - 在Microsoft Connect上有一个开放的反馈问题要求这个特性:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=168224
这表明它可能出现在未来的版本中,但未在当前版本中实施。
链接地址: http://www.djcxy.com/p/73055.html上一篇: Operator Overloading with C# Extension Methods
下一篇: what is the difference between overloading an operator inside or outside a class?