Расширение «WhenNull» для проверки на ноль и инициализации базового объекта через лямбду - PullRequest
3 голосов
/ 28 сентября 2010

Меня спросили, что не так / как можно исправить следующий сценарий

Customer customer = null;
customer.WhenNull(c => new Customer())
        .Foo();

// instead of
Customer customer = null;
if (customer == null)
{
   customer = new Customer();
}
customer.Foo();

Один разработчик отправляет мне свою версию расширения WhenNull

public static T WhenNull<T>(this T source, Action<T> nullAction)
{
   if (source != null)
   {
      return source;
   } 

   if (nullAction == null)
   {
       throw new ArgumentNullException("nullAction");
   }

   nullAction(source);

   return source;
}

Его проблема / намерение состоит в том, что он не хочет указывать базовый объект в лямбда-выражении (в данном случае «клиент»)

Customer customer = null;
customer.WhenNull(c => customer = new Customer())
        .Foo();

Я думал, что это невозможно сделать.
Это правильно?

Ответы [ 3 ]

7 голосов
/ 28 сентября 2010

Вы можете сделать:

static T WhenNull<T>(this T t) where T : class, new()
{
  return t ?? new T();
}

Также отмечено: вы хотите использовать Func<T>, а не Action<T> согласно вашему примеру кода.

Редактировать 2:

Вы, вероятно, хотите это:

static T WhenNull<T>(this T t, Func<T> init) where T : class
{
  if (t == null)
  {
    t = init();  // could return here, but for debugging this is easier
  }
  return t;
}

Использование:

something.WhenNull(() => new Something()).Foo()
2 голосов
/ 28 сентября 2010

Если вам действительно нужен сокращенный синтаксис, вы можете просто сделать:

(customer = customer ?? new Customer()).Foo();

Не рекомендую, хотя.

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

Вместо этого вы можете использовать Func :

public static T WhenNull<T>(this T source, Func<T> nullFunc)
{
   if (source != null)
   {
      return source;
   } 

   if (nullFunc == null)
   {
       throw new ArgumentNullException("nullFunc");
   }

   return nullFunc();
}

Или в качестве состояний леппи использовать оператор объединения и ограничение new (), если не хотите указывать лямбу.

...