문제

확장 메서드를 사용하여 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

향후 릴리스에 나타날 수 있지만 현재 버전에는 구현되지 않을 수 있습니다.

연산자를 할 수는 없지만 항상 추가 (또는 동의)를 만들고, 빼고, 방법을 비교할 수 있습니다 ....

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 += (사물)에 대해 정확히 같은 욕망으로 "확장 연산자 과부하"를 찾고있었습니다.

여기에서 답을 읽은 후 (그리고 대답이 "아니오"라는 것을 알게 된 후, 나의 특정 요구에 대해, 나는 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 모든 숫자 변환은 고정 해야하는 스트링 빌더에 쓰레기를 만듭니다. 나는 작동하는 래퍼를 써야했고 그것을 사용합니다. 그것은 잊을만한 가치가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top