Почему не поддерживаются методы расширения статического класса C#?



Я знаю, что от этот вопрос что методы расширения могут работать только с экземплярами класса, а не с самим статическим классом. Это означает, что я не могу расширить полезные статические классы, такие как Convert и Math.



что я хочу знать, почему это произошло? Из приведенной выше ссылки есть несколько предложений о том, как команда C# могла бы реализовать такую функциональность. Есть ли какая-то философская причина, почему она не поддерживается?



например, вот а обоснование за Почему нет встроенного LINQ

660   6  

6 ответов:

команда C# могла бы реализовать такую функциональность. Есть ли какая-то философская причина, почему она не поддерживается?

нет ни технической причины, ни философской. Однако, как я часто указываю, мне не нужно предоставлять обоснование для не выполнение функции. Особенности не дешевы; они чрезвычайно дороги, и они должны не только оправдать свою собственную стоимость, они должны оправдать альтернативные издержки не делать сотни других функций мы может сделать с этим бюджетом. Мы должны обосновать стоимость функций для наших заинтересованных сторон, но нам не нужно оправдывать экономию времени и усилий со стороны не реализация функций, которые не соответствуют нашему бару.

в частности, предложенная функция ничего не делает для LINQ; методы расширения были добавлены, чтобы заставить LINQ работать. Все, что не заставляло LINQ работать, было очень трудно попасть в C# 3.0; у нас было много работы по расписанию и не так много пора это сделать. (Я был удивлен, что автоматические свойства сделали его.) Вырезание ненужной функции еще до ее разработки сэкономило много времени и усилий, которые были потрачены на другие вещи, которые do заставить 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# и не нарушайте концепцию доступности ООП. Фактически, если вы пишете метод расширения и обычный статический метод, которые делают то же самое, а затем декомпилируют 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 - это просто синтаксический сахар, так как все, что он может do может быть написано неуклюжим, не LINQy способом. Очевидно, команда C# чувствовала, что читаемость, полученная LINQ, стоит того, но она задает вопрос: "почему они остановились на этом?"

почему не другие типы расширений?

Эрик Липперт, один из разработчиков компилятора C#, описанный в блоге что огромная часть C# 3 создавала все конструкции, необходимые для LINQ:"неявно типизированные локальные, анонимные типы, лямбда-выражения, расширение методы, инициализаторы объектов и коллекций, понимание запросов, деревья выражений, [и] улучшенный вывод типа метода." поскольку команда C# была самой ограниченной по ресурсам командой для выпуска .NET 2008 года, дополнительные типы расширений, которые не были строго необходимы для LINQ, не были включены.

команда рассматривала возможность реализации свойств расширения в C# 4 и фактически написала рабочий прототип, но он был удален, когда они обнаружили, что он не включит WPF команда, как реализовано (что было одним из мотиваторов для этой функции). Эрик Липпер позже сказал, что они рассмотрела методы расширения для статических классов, но не смогли оправдать реальные выгоды от затрат на реализацию, тестирование и техническое обслуживание.

решение

можно написать метод расширения, который приближается:

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 может вызвать его, и это, вероятно, не предполагаемая функциональность.

Я считаю, что ответ на ваш вопрос because it doesn't make any sense to extend with static methods. Основная причина введения Extension methods не extending класс, которым вы не владеете. Основная причина заключается в том, что это позволит уменьшить вложенность методов в таких примерах:

 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

вот почему нет такого пункта, чтобы иметь extension методы статических классов.

методы расширения работают с объектами, а не с классами. Если вы хотите, чтобы метод расширения работал с классом, я полагаю, вы могли бы сделать это:

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

статические расширения возможны в 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

ну его не только о не реализовано, но это вызовет путаницу, где метод принадлежит? Статические расширения были введены, потому что linq пришел в более поздней версии и только для поддержки linq в простой способ кодирования, статические расширения полезны.

статические расширения полезны только для того чтобы сделать код более читабельным. Он не имеет никакого значения во время выполнения или во время компиляции.

Comments

    Ничего не найдено.