IT story

C # 정적 클래스 확장 메서드가 지원되지 않는 이유는 무엇입니까?

hot-time 2020. 12. 30. 19:16
반응형

C # 정적 클래스 확장 메서드가 지원되지 않는 이유는 무엇입니까?


이 질문 에서 확장 메서드는 정적 클래스 자체가 아닌 클래스 인스턴스에서만 작동 할 수 있다는 것을 알고 있습니다. 이 방법은 내가 좋아하는 유용한 정적 클래스를 확장 할 수 없습니다 ConvertMath.

내가 알고 싶은 것은, 왜 이런 경우입니까? 위의 링크에서 C # 팀이 이러한 종류의 기능을 구현할 수 있었던 방법에 대한 몇 가지 제안이 있습니다. 지원되지 않는 철학적 인 이유가 있습니까?

예를 들어, 다음의 근거 없음이 내장 된 이유 LINQ의 배후 ForEach<T>에 대한 확장 IEnumerable<T>.


C # 팀은 이런 종류의 기능을 구현했을 수 있습니다. 지원되지 않는 철학적 인 이유가 있습니까?

기술적 이유도 철학적 이유도 없습니다. 그러나 자주 지적했듯이 기능을 수행 하지 않는 것에 대한 정당성을 제공 할 필요는 없습니다 . 기능은 저렴하지 않습니다. 비용이 매우 비싸고 자체 비용을 정당화해야 할뿐만 아니라 해당 예산으로 수행 있는 수백 가지 다른 기능을 수행하지 않는 기회 비용도 정당화해야합니다 . 우리는 우리의 이해 관계자들에게 기능의 비용을 정당화해야하지만, 우리는 시간과 노력을 절약 정당화 할 필요가 없습니다 우리 바를 충족하지 않는 기능을 구현.

특히 제안 된 기능은 LINQ에 대해 아무 작업도 수행하지 않습니다. LINQ가 작동하도록 확장 메서드가 추가되었습니다. LINQ가 작동하지 않는 모든 것은 C # 3.0에 들어가기가 매우 어려웠습니다. 일정에 많은 작업을했지만 시간이별로 없었습니다. 일 할 수는 LINQ 작업을합니다.

간단히 말해서, 제안 된 기능은 비용 대비 순이익에 대한 우리의 기준을 충족하지 못했으며 제한된 시간과 노력을 투자 할 수있는 더 중요한 기능이 항상있었습니다.


답변과 몇 가지 관련 질문을 읽은 후 여기에 문제에 대한 이해를 모았습니다.

확장 방법의 작동 방식

첫째, 확장은 정적 메서드의 구문 설탕 일 뿐이 라는 것을 인식하는 것이 중요 합니다.

// Say you have an extension method that looks like this:
class Extensions
{
    public static void Extend(this SomeClass foo) {}
}

// Here's how you call it
SomeClass myClass;
myClass.Extend();

// The compiler converts it to this:
Extensions.Extend(myClass);

이 메서드는 실제로 클래스의 일부가되지 않습니다. 이것이 확장 메서드에서 개인 멤버에 액세스수없는 이유 입니다. 확장 메서드는 C # 구문 만 변경하며 OOP 접근성 개념을 위반하지 않습니다. 실제로 확장 메서드와 동일한 작업을 수행하는 일반 정적 메서드를 작성한 다음 MSIL을 디 컴파일하면 정확히 동일 합니다.

확장 방법이 존재하는 이유

그래서 그들이 실제 기능을 추가하지 않는다면 왜 확장 메서드가있는 것일까 요? 대답은 LINQ입니다.

// LINQ makes this easy to read
array.Where(i => i&1 == 0).Select(i => i*i);

// Without extension methods, we would have to do it like this
Enumerable.Select(Enumerable.Where(array, i => i&1 == 0), i => i*i);

어떤면에서 LINQ가 할 수있는 모든 것은 LINQy가 아닌 투박한 방식으로 작성 될 수 있기 때문에 모든 LINQ는 구문상의 설탕 일뿐입니다. 분명히 C # 팀은 LINQ를 통해 얻은 가독성이 그만한 가치가 있다고 생각했지만 "왜 거기서 멈추었 을까요?"라는 질문을 던집니다.

다른 확장 유형이 아닌 이유는 무엇입니까?

C # 컴파일러 개발자 중 한 명인 Eric Lippert는 블로그 게시물 에서 C # 3의 대부분이 LINQ에 필요한 모든 구문을 만들고 있다고 설명했습니다 . "암시 적 형식의 로컬, 익명 형식, 람다 식, 확장 메서드, 개체 및 컬렉션 이니셜 라이저 , 쿼리 이해, 표현식 트리, [및] 개선 된 메소드 유형 추론. " C # 팀은 2008 .NET 릴리스에서 가장 리소스가 제한된 팀 이었기 때문에 LINQ에 꼭 필요하지 않은 추가 유형의 확장은 포함되지 않았습니다.

팀은 C # 4에서 확장 속성을 구현하는 것을 고려했고 실제로 작동하는 프로토 타입을 작성했지만 WPF 팀이 구현 된대로 사용할 수 없다는 사실을 발견했을 때 삭제되었습니다 (이 기능에 대한 동기 중 하나였습니다). Eric Lipper는 나중에 정적 클래스에 대한 확장 메서드를 고려 했지만 구현, 테스트 및 유지 관리 비용에 대한 실제 이점을 정당화 할 수 없다고 말했습니다 .

해결 방법

가까워지는 확장 메서드를 작성할 수 있습니다.

public static TResult DoSomething<TType, TResult>(this TType @class)
    {
        // access static methods with System.Reflection
        return default(TResult);
    }

// This works, but poorly
typeof(Math).DoSomething();
typeof(Convert).DoSomething();

그러나 그것은 매우 추합니다. 리플렉션이 필요하고 어떤 종류의 지능형 타이핑도 지원할 수 없습니다. 누구든지 Type호출 할 수 있고 의도 한 기능이 아닐 가능성이 있기 때문입니다.


I believe the answer for your question is because it doesn't make any sense to extend with static methods. Main reason behind introducing Extension methods is not extending class which you do not own. Main reason is that it will allow reduce methods nesting in examples like these:

 Enumerable.Select(Enumerable.Where(arr, i => i & 1 == 0), i => i*i); // not the best thing I ever read

 arr.Where(i => i&1 == 0).Select(i => i*i); // wow, I see! These are squares for odd numbers

That is why there is no such point to have extension methods for static classes.


Extension methods operate on objects, not classes. If you want an extension method to operate on a class, I suppose you could do this:

public static T DoSomething<T>(this T @class) 
    where T:Type
{
    // access static methods via reflection...
    return @class;
}

Static extensions are possible in F# :

type Platform = 
    | Win32
    | X64
    override this.ToString() = 
        match FSharpValue.GetUnionFields(this, typeof<Platform>) with
        | case, _ -> case.Name.Replace('X', 'x')

type Environment with
    static member Platform =
        if System.IntPtr.Size = 8 then Platform.X64 else Platform.Win32

Well its not only about not implemented, but it will cause confusion of where the method belongs to? Static extensions were introduced because linq came in later version and only to support linq in easy to code way, static extensions are useful.

Static extensions are useful only to make code more readable. It has no significance at runtime or compile time.

ReferenceURL : https://stackoverflow.com/questions/4909156/why-arent-c-sharp-static-class-extension-methods-supported

반응형