Является ли расширенная перегрузка оператора будущей возможностью? - PullRequest
0 голосов
/ 29 июня 2018

Я недавно получил в руки копию C # 7.0 в двух словах от Джозефа и Бена Албахари. Когда я просматривал главу, посвященную расширенному C #, в частности, стр. 199, где она начинается с перегрузки операторов; Я начал задаваться вопросом, было ли какое-либо официальное слово о перегрузке операторов, подобное методам расширения для хотя бы примитивных типов? Например:

// Traditional Overload
public static MyType operator +(MyType, MyType);

// Traditional Extension Method
public static int Sum(this int, int[]);

// Possible Combination?
public static int operator +(this int, int, string);

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

int sum = int.Sum(myArrayOfIntegers);

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

public static int operator +(this int i, int x, string y) {
    // Perform parsing of the string and return the newly added value between x and y.
}

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

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

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

Это все еще на нашем радаре для будущих выпусков. Что поможет, если мы получим достаточное количество убедительных сценариев, которые помогут создать правильный дизайн.

Все еще на нашем радаре, на мой взгляд, не очень многообещающе.

Пожалуйста, предоставляйте ответ только в том случае, если ресурс является достоверным и актуальным (или в течение предыдущих 2 лет).

1 Ответ

0 голосов
/ 30 июня 2018

Да, это так. В C # 8, скорее всего, будет «Extension Everything», как объяснено здесь на Github.

Что включает в себя «Расширение все»:

  • Расширение статических полей
  • Статические методы расширения
  • Расширение статических свойств
  • Свойства расширения
  • Удлинители
  • Удлинительный кастинг
  • Операторы расширения

Что не входит:

  • Поля экземпляра расширения (сначала)
  • Конструкторы расширения (сначала)
  • События расширения (сначала)
  • Автоматические свойства расширения (только если они не поддерживают поля экземпляра расширения)

Синтаксис, скорее всего, будет примерно таким:

public extension class List2DExt<T> : List<List<T>> 
{
    // Extension static field
    private static int _flattenCount = 0;

    // Extension static property
    public static int FlattenCount => _flattenCount;

    // Extension static method
    public static int Get FlattenCount() => _flattenCount;

    // New syntax for extension methods
    public List<T> Flatten() { ... }

    // Extension indexers
    public List<List<T>> this[int[] indices] => ...;

    // Extension implicit operator
    public static implicit operator List<T>(List<List<T>> self) => self.Flatten();

    // Extension operator overload
    public static implicit List<List<T>> operator +(List<List<T>> left, List<List<T>> right) => left.Concat(right);
}

Причина, по которой поля экземпляров сначала не поддерживаются, заключается в том, как им придется отслеживать состояние этих полей, что, как мне кажется, сложно.

...