Лямбда-выражения - PullRequest
       4

Лямбда-выражения

1 голос
/ 26 сентября 2010

Есть ли лучший способ избежать NullRefenrenceException, кроме try / catch

т.е.

x => x.Child.GChild.GChildProp1

Если Child или GChild окажутся нулевыми, очевидно, это вызовет NullRefenrenceException

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

что было бы лучше или это лучшее решение?

Ответы [ 4 ]

2 голосов
/ 26 сентября 2010

Ну, вы могли бы преобразовать это в дерево выражений, а не в делегат, и тщательно перемещаться по нему. Но нет, в C # нет ничего похожего на «нулевой безопасный оператор разыменования». Я полагаю, что команда C # изучила это и обнаружила, что трудно придумать что-то, что на самом деле работает так, как вы, естественно, хотите. Это не значит, что у них не будет другого взгляда на более позднюю дату, конечно:)

(Это, безусловно, звучит как относительно простая языковая функция для реализации ... но я доверяю команде, когда они говорят, что есть скрытые сложности!)

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

0 голосов
/ 26 сентября 2010

Исключения следует выдавать только в исключительных случаях, т. Е. В тех случаях, когда это невозможно учесть (т. Е. Нехватка памяти и т. Д.). Использование try / catch для случаев, подобных выше, считается плохой практикой (по причинам производительности и возможности отладки и т. Д.), И его можно избежать, проверив нулевые ссылки, т.е.

x => { if (x.Child != null && x.Child.GChild != null) x.Child.GChild.GChildProp1; };

С уважением, Christian

0 голосов
/ 26 сентября 2010

Хммм, есть что-то принципиально не так с этим?

myList.Where(x => x.Child != null && x.Child.GChild != null).Select(x => x.Child.GChild.GChildProp1);

или:

var z = from x in myList
        where x.Child != null && x.Child.GChild != null
        select x.Child.GChild.GChildProp1;

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

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

0 голосов
/ 26 сентября 2010

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

public static R TryGet<T,R>(T obj, Func<T,R> getProperty) {
  if (obj == null) {
    return default(R);
  } else {
    return getProperty(obj);
  }
}

Теперь вы можете использовать это, чтобы попытаться получить свойство:

x => TryGet(TryGet(TryGet(x, y => y.Child), y => y.GChild), y => y.GChildProp1);

Если вы получите нулевую ссылку в пути, вы получите значение по умолчанию для конечного свойства (которое равно нулю, если это ссылочный тип).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...