Если вы контролируете места, где вы хотите использовать этот «оператор расширения» (что вы обычно делаете с методами расширения), вы можете сделать что-то вроде этого:
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
более понятным.