Еще одно полезное использование для Dispatcher.Invoke
- это немедленное обновление пользовательского интерфейса в функции, выполняющей другие задачи:
// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
Я использую это, чтобы обновить текст кнопки до « Обработка ... "и отключить его при выполнении запросов WebClient
.
В целом команда разработчиков языка C# консервативна о добавлении нового синтаксиса. Они говорят, что значение дополнения к языку должно быть взвешено против стоимости увеличенной сложности на языке.
Peter Hallam был выводом разработки Компилятора C# некоторое время и также членом команды разработчиков языка C#. Он записал о своем способе измерить новую возможность, названную Критерий , хотя он был сфокусирован больше на интерактивных функциях GUI, чем функции языка.
Этот текст особенно относится к вопросу ??=
:
Часто правильное проектное решение ничего не состоит в том, чтобы изменить. Это - вероятно, самый важный урок, который я извлек из наблюдения Anders на встречах дизайна языка C#. Часто область языка повышена, в котором там, кажется, некоторые реальные усиления, которые могли быть сделаны. Мы могли предотвратить пользователя от общей ошибки кодирования, или мы могли улучшить usabilityof язык для определенной проблемной области. Затем после размышления действительно трудно, через все опции для того, чтобы решить проблему, ответ должен сделать.... ничего! Даже при том, что проблема допустима, и похоже, что мы должны смочь добавить что-то для улучшения ситуации после тщательного отражения, там не способ решить проблему, которая не стоит больше, чем усиления решения. Многие самые важные и ценные решения, которые я видел, что Anders принимает, являются решениями не добавить сложность к языку, если добавленная стоимость не выравнивает по ширине сложность. В промежуточных случаях, он почти всегда choses ничто по добавлению чего-то, что является крайним.
Когда я думаю об этом,
foo = foo ?? x
действительно всего
foo = foo != null ? foo : x
и в той точке, аналогия с + = начинает разваливаться.
Нет никакой причины, почему там не мог быть таким оператором, но я подозреваю, что добавленная сложность языка, хотя небольшой, перевешивает преимущество (который я считал бы "очень небольшим").
В основном любое дополнение к языку имеет довольно высокую панель для очистки. Вы говорите использование этого довольно часто - как часто, действительно? В то время как я считаю ??
удобный, я не могу сказать, что использую даже это ужасно часто.
??
не "оператор" в том смысле, что он делает "операцию" со значением операндов. Необходимо просмотреть его как конструкция языка .
предположим Вы имели:
node = node.next;
Вы затем хотели бы смочь сделать следующее?
node .= next;
я думаю ??=
, не существует по той же причине, которая .=
не существует.
Кроме того, унарные операторы как +=
, *=
, и т.д. имеют прямые дубликаты на уровне ассемблера. Псевдоблок:
add reg0, 1
mul reg1, 5
просто "естественно", что эти операторы существуют.
Нет никакого оператора, который выполняет эту операцию. Однако это - интересное предложение для будущей версии языка. Я подозреваю, что это не было включено к настоящему времени, потому что основной пример использования для оператора объединения, ??
, с типом Nullable и получением значения как в:
int? testValue;
return testValue ?? 0;
, А не в операциях присвоения как Ваш пример. Кроме того, тогда как +=
, как гарантируют, изменит значение нечто во всех случаях, но += 0
, ??=
не был бы.
Существует намного более простой ответ, который все пропускают при обсуждении, имеет ли аналогия ??=
к +=
смысл.
Вопрос: Почему Вы не можете сделать foo ??= x;
в C#?
Ответ: Поскольку каждая функция запускается с минус 100 точек , , функции начинаются не существующий, и кто-то должен заставить их произойти и скорее всего если бы они добавили ту опцию, , те ресурсы были потрачены на что-то, что обладало бы большим общим преимуществом для клиентской базы :
... думают все время и усилие, необходимое, чтобы разработать, как функция должна работать, гвоздь все граничные условия, затем кодировать его, запишите автоматизированные тесты для него... опишите документацию и текст справки, и продолжите поддерживать код, тесты и документацию в течение ожидаемого времени жизни функции (который в этом случае является, вероятно, навсегда). Все те ресурсы, возможно, были потрачены на что-то, что обладало бы большим общим преимуществом для клиентской базы? (Ответ на это всегда - "Да "—, все и ее невестка могут найти способ закончить предложение, "Я не могу полагать, что они потратили впустую все то время на эту глупую функцию вместо того, чтобы фиксировать...")
Я не вижу многих оснований, почему Вы использовали бы?? оператор для самоприсваивания переменной.
, Возможно, Вы основаны на установке foo
некоторое значение базы данных, которое, оказывается, NULL
, таким образом, имело бы больше смысла использовать?? оператор во время того присвоения (который избавляет от необходимости?? =):
foo = (int?)rows["possiblyNullCount"] ?? 0;
в противоположность:
foo = (int?)rows["possiblyNullCount"];
foo = foo ?? 0;
Главным образом, потому что + =, - = и т.д. были добавлены в значительной степени как запоздалые мысли для поддержания совместимости с C & C++. (*) С тех пор?? не часть C или C++, не было никакой потребности добавить дополнительный оператор.
(*) Примечание, что в C++, при определении операторов для класса, каждый обычно определяет оператор + = () и затем реализует оператор + () на основе его. (Это обычно - самый эффективный путь). Однако в C#, каждый реализует оператор +, и компилятор автоматически добавляет оператор + = на основе oper +. Поэтому я говорю, что + = операторы являются прикрепляемым на запоздалой мысли.
В то время как не точно, что Вы просите (это не?? =)... Вы могли, возможно, усилить Дополнительные Методы.
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;
}
}
я не провел исчерпывающее количество времени, думающее о возможных способах, которыми это не будет работать, но это, действительно кажется, проходит тест запаха в моем примере приложения...
Я пропускаю его также - Ruby разрушил меня. Вот подобная конструкция, которую можно использовать в выражении (если у Вас не аллергия на побочные эффекты):
foo ?? foo = x;
как в:
return foo ?? foo = x;
или (для иллюстрации только!):
DoStuff( foo ?? foo = x );
Используя этот шаблон за пределами метода считывания свойства, вероятно, не прекрасная идея.
Тот стиль оператора чувствует себя подобно ленивой загрузке из метода считывания свойства. В этом случае я выбрал бы этот синтаксис
private Foo myFoo;
public Foo MyFoo
{
get
{
return myFoo ?? (myFoo = new Foo());
}
}
Поскольку существует не такой?? = оператор в C#.
, Пока + = может походить на два оператора, представленные с другим синтаксисом его всего один оператор.