Нулевое объединение в цепочке вызовов - PullRequest
2 голосов
/ 10 февраля 2011

Если у меня длинный список объектов, каждый из которых имеет возможность вернуть ноль в предложении «Linq where», например,

 SomeSource.Where(srcItem=>(srcItem.DataMembers["SomeText"].Connection.ConnectedTo as Type1).Handler.ForceInvocation == true));

индексатор может возвращать ноль, а оператор «как» может возвращать ноль. Возможно, что объект не имеет связи (т.е. свойство имеет значение null). Если где-либо встречается нуль, я бы хотел, чтобы предложение where возвращало «false» для оцениваемого элемента. Вместо этого он прерывается с исключением нулевой ссылки.

Мне кажется, что это было бы придумано для выражения в одном выражении C #. Мне не нравится создавать многострочный оператор или создавать для него отдельный функционал. Есть ли какое-то использование оператора объединения нулей, который я пропускаю?

Ответы [ 4 ]

2 голосов
/ 10 февраля 2011

Вы ищете оператор .? (или это ?. - один из тех, во всяком случае), которого нет в C # (хотя, по словам Эрика Липперта, это часто запрашиваемая функция).

Единственное возможное предложение, которое у меня есть, - это написать метод, который принимает выражение и использует it для проверки любых нулей.Но это будет стоить производительности.В любом случае, это может выглядеть так:

T TryOrDefault<T>(Expression<Func<T>> expression)
{
    // Check every MemberExpression within expression one by one,
    // looking for any nulls along the way.

    // If a null is found, return default(T) or some default value.

    // Otherwise...
    Func<T> func = expression.Compile();
    return func();
}
2 голосов
/ 10 февраля 2011

Используя оператор и из Ruby для вдохновения, вы можете создать метод расширения, который будет действовать как нулевой защитник.

public static U AndAnd<T, U>(this T obj, Func<T, U> func)
{
    return obj == null ? default(U) : func(obj);
}

Ваш оригинальный код может быть переписан следующим образом:

SomeSource.Where(srcItem => (srcItem.AndAnd(val => val.DataMembers["SomeText"]).AndAnd(val => val.Connection).AndAnd(val => val.ConnectedTo) as Type1).AndAnd(val => val.Handler).AndAnd(val => val.ForceInvocation));

Будьте осторожны при возврате типов не-булевых значений с помощью этого метода - убедитесь, что вы знакомы со значениями , возвращаемыми default(U).

0 голосов
/ 21 июня 2012

Некоторое время назад я написал проект, имитирующий AndA и опирающийся на DynamicProxy.Он отлично работает, хотя я не использовал его в продукт.Единственным недостатком является то, что он требует, чтобы все члены были виртуальными или возвращаемые типы были интерфейсом, чтобы DynamicProxy мог делать свое волшебство.

Проверьте здесь https://bitbucket.org/mamadero/andand/overview

0 голосов
/ 10 февраля 2011

создайте для него отдельную функцию

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

...