Почему C # не разрешает функции, не являющиеся членами, такие как C ++ - PullRequest
64 голосов
/ 21 июня 2009

C # не позволит писать функции, не являющиеся членами, и каждый метод должен быть частью класса. Я думал, что это ограничение на всех языках CLI. Но я ошибся и обнаружил, что C ++ / CLI поддерживает функции, не являющиеся членами. Когда он скомпилирован, компилятор сделает метод членом какого-то безымянного класса.

Вот что говорит стандарт C ++ / CLI:

[Примечание: функции, не являющиеся членами, обрабатываются CLI как члены некоторого безымянного класса; однако в исходном коде C ++ / CLI такие функции не могут быть явно определены с этим именем класса. конечная нота]

Кодирование не входящих в метаданные функций не определено. [Примечание: это не вызывает проблем взаимодействия, потому что такие функции не могут иметь публичную видимость. конечная нота]

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

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

Есть мысли ...?

Ответы [ 12 ]

0 голосов
/ 26 ноября 2017

Бесплатные функции очень полезны, если вы комбинируете их с набором текста. Весь C ++ STL основан на этом. Поэтому я уверен, что C # представит бесплатные функции, когда им удастся добавить настоящие обобщения.

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

0 голосов
/ 07 марта 2017

Если подумать, контраргументом будет "почему C ++ не поддерживает методы расширения" , и ответ лежит в их целях разработки.

C ++ предоставляет вам функции пространства имен, которые вы можете вызывать для любого объекта, которые помогут вам каким-то образом "расширить" этот объект.

В большинстве случаев я использовал функции пространства имен в C ++ для создания функций, принимающих объекты и выполняющих функции, которые я не хочу помещать в функцию-член класса.

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

Возьмите следующий код, например:

template<typename T>
unsigned int findCount(vector<T>& vec, T data){
    unsigned int count = 0;
    for(auto val : vec)
        if(val == data) ++count;
    return count;
}

Теперь, если мне понадобится эта функциональность для какой-то цели в моем классе, я могу просто добавить ее в пространство имен класса и использовать ее, не "загрязняя" мой класс этой функцией.

В C # вы можете достичь той же цели с помощью метода расширения:

static class Extensions {
    public static uint FindCount<T>(this List<T> list, T data) {
        uint counts = 0;
        foreach (var item in list)
            if (item.Equals(data)) ++counts;
        return counts;
    }
}

И оба они работают одинаково, что круто. Многие будут спорить о том, что в C ++ отсутствуют методы расширения, многие будут спорить о том, что в C # отсутствуют функции пространства имен.

Я думаю, что лучший способ выразить это - не сравнивать эти языки с некоторыми деталями, потому что это разные языки с разными реализациями.

Как вы цитировали в своем вопросе, C ++ / CLI не "на самом деле" поддерживает функции-члены пространства имен, поскольку он добавляет безымянный класс для их использования, который никоим образом не близок к Реализация на C ++, возможно, близка по внешнему виду, но действительно отличается.

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

...