확장 메서드를 사용하여 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
는이 문맥에서 허용되지 않습니다.
확장 방법을 통해 연산자 과부하를 추가 할 수 있습니까? 그렇다면 적절한 방법은 무엇입니까?
답변
확장 메서드는 정적 클래스에 있어야하며 정적 클래스에는 연산자 오버로드를 가질 수 없으므로 현재는 불가능합니다.
C # Language PM의 Mads Torgersen은 다음과 같이 말합니다.
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
클래스가 선언 암시 적 변환 연산자 (A)로부터 StringBuilder
그리고 원하는 선언 +
오퍼레이터. 이런 식으로 a 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
향후 릴리스에 표시 될 수 있지만 현재 버전에는 구현되지 않았 음을 제안합니다.
답변
연산자를 수행 할 수는 없지만 항상 추가 (또는 Concat), 빼기 및 비교 메소드를 작성할 수 있습니다.
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;
}
}
}
답변
하! 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);
일반적인 대답은 아니지만, 이런 종류의 것을보고있는 미래의 구직자들에게는 관심이있을 수 있습니다.
답변
래퍼와 확장 프로그램으로 조작 할 수는 있지만 제대로 수행 할 수는 없습니다. 당신은 목적을 완전히 물리 치는 쓰레기로 끝납니다. 여기 어딘가에 게시물이 있지만 그 가치가 없습니다.
Btw 모든 숫자 변환은 수정해야하는 문자열 빌더에서 가비지를 작성합니다. 작동하는 래퍼를 작성하여 사용했습니다. 그것은 가치가 있습니다.