Уникальные способы использовать оператор Null Coalescing

8 ответов

Ну, в первую очередь, это намного легче к цепочке, чем троичный стандарт:

string anybody = parm1 ?? localDefault ?? globalDefault;

по сравнению с

string anyboby = (parm1 != null) ? parm1 
               : ((localDefault != null) ? localDefault 
               : globalDefault);

Это также работает хорошо, если пустой возможный объект не является переменной:

string anybody = Parameters["Name"] 
              ?? Settings["Name"] 
              ?? GlobalSetting["Name"];

по сравнению с

string anybody = (Parameters["Name"] != null ? Parameters["Name"] 
                 : (Settings["Name"] != null) ? Settings["Name"]
                 :  GlobalSetting["Name"];
208
ответ дан James Curran 23 November 2019 в 21:42
поделиться

Охладитесь! Считайте меня как кого-то, кто не знал о пустом операторе объединения - это - довольно изящный материал.

я нахожу намного легче читать, чем тернарный оператор.

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

public void someMethod( object parm2, ArrayList parm3 )
{ 
  someMethod( null, parm2, parm3 );
}
public void someMethod( string parm1, ArrayList parm3 )
{
  someMethod( parm1, null, parm3 );
}
public void someMethod( string parm1, object parm2, )
{
  someMethod( parm1, parm2, null );
}
public void someMethod( string parm1 )
{
  someMethod( parm1, null, null );
}
public void someMethod( object parm2 )
{
  someMethod( null, parm2, null );
}
public void someMethod( ArrayList parm3 )
{
  someMethod( null, null, parm3 );
}
public void someMethod( string parm1, object parm2, ArrayList parm3 )
{
  // Set your default parameters here rather than scattered through the above function overloads
  parm1 = parm1 ?? "Default User Name";
  parm2 = parm2 ?? GetCurrentUserObj();
  parm3 = parm3 ?? DefaultCustomerList;

  // Do the rest of the stuff here
}
3
ответ дан HanClinto 23 November 2019 в 21:42
поделиться

?? необходимый, или если Вы просто используете тернарный оператор (с которым большинство знакомо)

необходимо использовать что лучшие экспрессы намерение. С тех пор там , пустой указатель объединяет оператор, использование это .

, С другой стороны, так как это так специализировано, я не думаю, что это имеет другое использование. Я предпочел бы соответствующую перегрузку || оператор, как другие языки делают. Это было бы более экономно в дизайне языка. Но хорошо †¦

3
ответ дан Konrad Rudolph 23 November 2019 в 21:42
поделиться

Только проблемой является пустой указатель - объединяют оператор, не обнаруживает пустые строки.

<час>

т.е.

string result1 = string.empty ?? "dead code!";

string result2 = null ?? "coalesced!";

ВЫВОД:

result1 = ""

result2 = coalesced!
<час>

я в настоящее время изучаю переопределение?? оператор для работы вокруг этого. Уверенный было бы удобно встроить это в Платформу.

Мысли?

4
ответ дан Kevin Panko 23 November 2019 в 21:42
поделиться

Я использовал?? в моей реализации IDataErrorInfo:

public string Error
{
    get
    {
        return this["Name"] ?? this["Address"] ?? this["Phone"];
    }
}

public string this[string columnName]
{
    get { ... }
}

, Если отдельное свойство находится по "ошибке", указывают, что я получаю ту ошибку, иначе я становлюсь пустым. Работы действительно хорошо.

9
ответ дан Matt Hamilton 23 November 2019 в 21:42
поделиться

Я нашел его полезным двумя "немного нечетными" способами:

  • Как альтернатива для того, чтобы иметь out параметр при записи TryParse стандартные программы (т.е. возврат нулевое значение при парсинге сбоев)
  • Как "не знают" представления для сравнений

последние потребности немного больше информации. Обычно при создании сравнения с несколькими элементами необходимо видеть, дает ли первая часть сравнения (например, возраст) категорический ответ, тогда следующая часть (например, имя), только если первая часть не помогла. Используя пустое объединение оператор означает, что можно записать довольно простые сравнения (ли для упорядочивания или равенства). Например, с помощью нескольких классов помощника в MiscUtil:

public int Compare(Person p1, Person p2)
{
    return PartialComparer.Compare(p1.Age, p2.Age)
        ?? PartialComparer.Compare(p1.Name, p2.Name)
        ?? PartialComparer.Compare(p1.Salary, p2.Salary)
        ?? 0;
}

По общему признанию у меня теперь есть ProjectionComparer в MiscUtil, наряду с некоторыми расширениями, которые делают такого рода вещь еще легче - но это все еще аккуратно.

то же может быть сделано для проверки ссылочное равенство (или ничтожность) в начале реализации Равняется.

51
ответ дан Jon Skeet 23 November 2019 в 21:42
поделиться

Другое преимущество состоит в том, что тернарный оператор требует двойной оценки или временной переменной.

Рассматривают это, например:

string result = MyMethod() ?? "default value";

, в то время как с тернарным оператором с Вами оставляют также:

string result = (MyMethod () != null ? MyMethod () : "default value");

, который называет MyMethod дважды, или:

string methodResult = MyMethod ();
string result = (methodResult != null ? methodResult : "default value");

Так или иначе, пустой оператор объединения является более чистым и, я предполагаю, более эффективный.

33
ответ дан 23 November 2019 в 21:42
поделиться

Я использовал его в качестве ленивой остроты загрузки:

public MyClass LazyProp
{
    get { return lazyField ?? (lazyField = new MyClass()); }
}

Читаемый? Решите для себя.

173
ответ дан Cristian Libardo 23 November 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: