Подтвердить что ты не робот

Почему я не могу делать? = В С#?

Я часто нахожу себя:

foo = foo ?? x;

Почему я не могу:

foo ??= x;

Изменить: Я знаю, что это не часть языка... Мой вопрос "почему бы и нет"? Я нахожу необходимость повторять "foo", чтобы быть неудовлетворительным и потенциально подверженным ошибкам. Это выглядит так же безобразно, как:

foo = foo + x;
4b9b3361

Ответ 1

В общем, команда разработчиков языка С# консервативна в отношении добавления нового синтаксиса. Они говорят, что ценность добавления к языку должна быть сопоставлена ​​с стоимостью повышенной сложности языка.

Питер Халлам некоторое время был лидером по разработке компилятора С#, а также членом команды разработчиков языка С#. Он писал о своем способе измерения новой функции, называемой Yardstick, хотя он больше ориентировался на интерактивные функции графического интерфейса, а не на языковые функции.

Этот текст особенно важен для вопроса ??=:

Часто правильное дизайнерское решение ничего не меняйте. Это, вероятно, самый важный урок, который я изучил от просмотра Андерса в С# языковые проекты. Часто область языка поднимается в которые, как представляется, являются реальными выгоды, которые могут быть сделаны. Мы могли бы не допускать пользователя от общего кодирования ошибки, или мы могли бы улучшить удобство использования языка для определенного проблемный домен. Затем, подумав действительно трудно, через все варианты решения проблемы, ответ - делать.... ничего! Даже хотя проблема действительно, и это похоже, мы должны быть в состоянии добавить что-то улучшить ситуацию, после тщательного размышления нет способ решения проблемы, которая не стоить больше, чем выигрыш в решении. Многие из наиболее важных и ценные решения, которые я видел Андерс make - это решения не добавлять сложность языка, если добавленная стоимость оправдывает сложность. В пограничных случаях он все время ничего не делает что-то незначительное.

Литература:

Ответ 2

Когда я думаю об этом,

foo = foo ?? x 

действительно просто

foo = foo != null ? foo : x

и в этот момент аналогия с + = начинает разваливаться.

Ответ 3

Нет причин, почему такого оператора не может быть, но я подозреваю, что добавленная сложность языка, хотя и незначительная, перевешивает преимущество (которое я считаю "очень незначительным" ).

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

Ответ 4

?? не является "оператором" в том смысле, что он выполняет "операцию" со значением операндов. Вы должны рассматривать его как конструктор языка .

Предположим, что у вас было:

node = node.next;

Вы хотели бы иметь возможность сделать следующее?

node .= next;

Я думаю, что ??= не существует по той же причине, что .= не существует.

Кроме того, унарные операторы типа +=, *= и т.д. имеют прямые копии на уровне сборки. Псевдо-сборки:

add reg0, 1
mul reg1, 5

Это просто "естественно", что эти операторы существуют.

Ответ 5

Нет оператора, который выполняет эту операцию. Однако это интересное предложение для будущей версии языка. Я подозреваю, что он до сих пор не включен, потому что основной вариант использования оператора коалесценции ?? имеет тип Nullable и получает значение как в:

int? testValue;

return testValue ?? 0;

Вместо операций присваивания, подобных вашему примеру. Кроме того, в то время как += гарантированно изменяет значение foo во всех случаях, но += 0, ??= не будет.

Ответ 6

Там гораздо проще ответить, что все не хватает, обсуждая, имеет ли смысл ??= to +=.

Вопрос: Почему вы не можете сделать foo ??= x; в С#?

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

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

Ответ 7

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

Возможно, вы устанавливаете foo на основе некоторого значения базы данных, которое бывает NULL, поэтому было бы разумнее использовать? оператор во время этого назначения (что устраняет необходимость в?? =):

foo = (int?)rows["possiblyNullCount"] ?? 0;

в отличие от:

foo = (int?)rows["possiblyNullCount"];
foo = foo ?? 0;

Ответ 8

В основном потому, что + =, - = и т.д. были добавлены в значительной степени как запоздалые мысли, чтобы поддерживать совместимость с C и С++. (*) Поскольку?? не является частью C или С++, не нужно было добавлять дополнительный оператор.

(*) Заметим, что в С++ при определении операторов для класса обычно определяется оператор + =(), а затем реализуется на нем оператор +(). (Это обычно самый эффективный способ). Однако в С# один реализует оператор +, и компилятор автоматически добавляет оператор + = на основе функции oper+. Вот почему я говорю, что операторы + = привязаны к запоздалой мысли.

Ответ 9

Пока не совсем то, о чем вы просите (это не?? =)... Возможно, вы можете использовать методы расширения.

static void Main(string[] args)
{
    object foo = null;
    object x = "something";
    Console.WriteLine(foo.NullToValue(x));
}

public static class ObjectExtensions
{
    public static object NullToValue(this object obj, object value)
    {
        return obj != null ? obj : value;
    }
}

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

Ответ 10

Этот стиль выражения похож на ленивую загрузку с объекта getter. В этом случае я бы выбрал этот синтаксис

private Foo myFoo;
public Foo MyFoo
{
    get
    {
        return myFoo ?? (myFoo = new Foo());
    }
}

Ответ 11

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

foo ?? foo = x;

как в:

return foo ?? foo = x;

или (только для иллюстрации!):

DoStuff( foo ?? foo = x );

Использование этого шаблона вне свойства getter, вероятно, не является отличной идеей.

Ответ 12

Поскольку в С# нет такого? = оператора.

В то время как + = может показаться, что два оператора, представленные с различным синтаксисом, представляют собой только один оператор.