[c#] C # 확장 메서드로 클래스를 확장하려면 어떻게해야합니까?

확장 메서드를 클래스에 적용 할 수 있습니까?

예를 들어 다음과 같이 호출 할 수있는 Tomorrow () 메서드를 포함하도록 DateTime을 확장합니다.

DateTime.Tomorrow();

내가 사용할 수 있다는 걸 알아

static DateTime Tomorrow(this Datetime value) { //... }

또는

public static MyClass {
  public static Tomorrow() { //... }
}

비슷한 결과를 얻을 수 있지만 DateTime.Tomorrow를 호출 할 수 있도록 DateTime을 어떻게 확장 할 수 있습니까?



답변

기존 유형이 부분으로 표시되지 않는 한 기존 유형에 메소드를 추가 할 수 없습니다 . 확장 메소드를 통해 기존 유형의 멤버로 보이는 메소드 만 추가 할 수 있습니다 . 이 경우 확장 메서드는 해당 형식의 인스턴스를 사용하므로 형식 자체에 정적 메서드를 추가 할 수 없습니다.

다음과 같은 정적 도우미 메서드를 만드는 데 방해가되는 것은 없습니다.

static class DateTimeHelper
{
    public static DateTime Tomorrow
    {
        get { return DateTime.Now.AddDays(1); }
    }
}

다음과 같이 사용합니다.

DateTime tomorrow = DateTimeHelper.Tomorrow;


답변

확장 방법을 사용하십시오 .

전의:

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        public static DateTime Tomorrow(this DateTime date)
        {
            return date.AddDays(1);
        }    
    }
}

용법:

DateTime.Now.Tomorrow();

또는

AnyObjectOfTypeDateTime.Tomorrow();


답변

확장 메서드는 첫 번째 매개 변수가 T 유형의 인스턴스 인 정적 메서드를 T의 인스턴스 메서드 인 것처럼 보이게 만들기위한 구문 설탕입니다.

따라서 ‘정적 확장 메서드’를 만들면 확장 메서드보다 코드 독자를 혼란스럽게 할 수 있으므로 이점이 크게 손실됩니다 (완전한 것으로 보이지만 실제로 해당 클래스에 정의되어 있지 않기 때문입니다). 구문 상 이득이 없습니다 (예를 들어 Linq 내에서 유창한 스타일로 통화를 연결할 수 있음).

어쨌든 using을 사용하여 확장을 범위로 가져와야하므로 생성하는 것이 더 간단하고 안전하다고 주장합니다.

public static class DateTimeUtils
{
    public static DateTime Tomorrow { get { ... } }
}

그리고 다음을 통해 코드에서 이것을 사용하십시오.

WriteLine("{0}", DateTimeUtils.Tomorrow)


답변

내가 답을 얻을 수있는 가장 가까운 방법은 System.Type객체에 확장 메서드를 추가하는 것입니다. 예쁘지는 않지만 여전히 흥미 롭습니다.

public static class Foo
{
    public static void Bar()
    {
        var now = DateTime.Now;
        var tomorrow = typeof(DateTime).Tomorrow();
    }

    public static DateTime Tomorrow(this System.Type type)
    {
        if (type == typeof(DateTime)) {
            return DateTime.Now.AddDays(1);
        } else {
            throw new InvalidOperationException();
        }
    }
}

그렇지 않으면 IMO Andrew와 ShuggyCoUk가 더 나은 구현을 가지고 있습니다.


답변

나는 Kumu와 똑같이 할 것입니다

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        public static DateTime Tomorrow(this DateTime date)
        {
           return date.AddDays(1);
        }
    }
}

그러나 이것을 new DateTime (). Tomorrow ();

DateTime.Now.Tomorrow ();보다 더 많이 본다고 생각하십시오.


답변

유형을 수정할 필요없이 새 메소드를 추가하여 기존 유형을 확장하는 기능을 제공합니다. 인스턴스 메서드 구문을 사용하여 응용 프로그램 내의 확장 된 유형의 개체에서 메서드를 호출하는 것을“확장 ”메서드라고합니다. 확장 메서드는 형식의 인스턴스 멤버가 아닙니다. 기억해야 할 요점은 정적 메서드로 정의 된 확장 메서드는 using 지시문을 통해 네임 스페이스를 애플리케이션 소스 코드로 명시 적으로 가져올 때만 범위 내에 있다는 것입니다. 확장 메서드는 정적 메서드로 정의되어 있지만 인스턴스 구문을 사용하여 호출됩니다.

여기에서 전체 예제를 확인하십시오.
http://www.dotnetreaders.com/articles/Extension_methods_in_C-sharp.net,Methods_in_C_-sharp/201

예:

class Extension
    {
        static void Main(string[] args)
        {
            string s = "sudhakar";
            Console.WriteLine(s.GetWordCount());
            Console.ReadLine();
        }

    }
    public static class MyMathExtension
    {

        public static int GetWordCount(this System.String mystring)
        {
            return mystring.Length;
        }
    }


답변

나는 비슷한 것을 찾고 있었다-확장 메서드를 제공하는 클래스에 대한 제약 목록. 간결한 목록을 찾기가 어려우므로 여기에 있습니다.

  1. 필드, 메서드 등의 개인 또는 보호 된 항목을 가질 수 없습니다.

  2. 에서와 같이 정적 클래스 여야합니다 public static class....

  3. 메서드 만 클래스에있을 수 있으며 모두 공용 정적이어야합니다.

  4. 기존의 정적 메서드를 사용할 수 없습니다. this 인수를 포함하지 않는 메서드는 허용되지 않습니다.

  5. 모든 방법은 시작해야합니다.

    public static ReturnType MethodName (this ClassName _this, …)

따라서 첫 번째 인수는 항상 this 참조입니다.

이로 인해 발생하는 암시 적 문제가 있습니다. 어떤 종류의 잠금이 필요한 메서드를 추가하면 클래스 수준에서 실제로 제공 할 수 없습니다. 일반적으로 비공개 인스턴스 수준 잠금을 제공하지만 비공개 필드를 추가 할 수 없으므로 일부 외부 클래스에서 공개 정적으로 제공하는 등 매우 어색한 옵션이 남습니다. 징후는 C # 언어의 종류 이들에 대한 설계에 나쁜 차례의했다 .

해결 방법은 Extension Method 클래스를 일반 클래스에 대한 Facade로 사용하고 Extension 클래스의 모든 정적 메서드 는 Singleton을 사용하여 실제 클래스를 호출하는 것입니다 .