2016-12-05 6 views
3

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

public static bool DoesNotExist(this object toCheck) 
{ 
    return toCheck == null; 
} 

обычно я использую его, как это:

if(myObject.DoesNotExist()) 
{ 
} 

У меня есть выражение, которое содержит условное выражение доступа, как этот

if (myObject?.MyProperty == null) 

который компилятор доволен. Если я это выражение использовать мой метод расширения, например:

if (myObject?.MyProperty.DoesNotExist()) 

тогда я получаю ошибку компилятора

CS0266 Не может неявно преобразовать тип "BOOL? на "bool". Явное преобразование существует (вам не хватает литой?)

Тип MyProperty - это какой-то объект из моего домена, а не bool.

Почему это происходит, и могу ли я предотвратить его?

+2

'if ((myObject? .MyProperty) .DoesNotExist())', похоже, работает, хотя – haim770

+0

@ haim770th это интересно. Спасибо за это, я мог бы использовать это. –

ответ

8

Нулевое условное выражение всегда имеет тип возвращаемого значения null - в конце концов, он должен иметь общий результат null, если левая сторона равна нулю.

Таким образом, тип myObject?.MyProperty.DoesNotExist() - Nullable<bool>, который не может использоваться как условие для заявления if.

Это легко исправить либо путем прямого сравнения с bool константой, или с помощью нуль-оператор коалесцирующий:

if (myObject?.MyProperty.DoesNotExist() == true) 

if (myObject?.MyProperty.DoesNotExist() ?? false) 

В обоих этих случаях, если myObject имеет нулевое значение, выполнение не будет входить в тело заявление if. Если вы хотите, противоположное поведение, вы можете использовать:

if (myObject?.MyProperty.DoesNotExist() != false) 

if (myObject?.MyProperty.DoesNotExist() ?? true) 

Однако, я не уверен, что ваш метод расширения на самом деле полезный один - по крайней мере, не здесь. Если вы просто делаете сравнение нуль, сделать это прямо:

if (myObject?.MyProperty == null) 

Это войдет в тело if заявления, если либоmyObject имеет нулевое значение, илиmyObject.MyProperty равна нулю.

+0

Спасибо. Проблема возникла, когда я пишу анализатор roslyn, который предлагает изменить '== null', чтобы использовать' DoNotExist', и удалил предложение автоматического исправления для выражений, которые содержат выражение условного доступа, которое кажется разумным предмет сделать здесь. –

+1

@SamHolder: Правильно, в этом случае вы, вероятно, хотите '?? true'. Хотя лично я все равно отговаривал, так как мне кажется, что в версии '== null' проще ... –

+0

Да, я буду придерживаться версии '== null' в этой ситуации, я думаю, если я не окружу все выражение в дополнительном наборе скобок как' (myObject? .MyProperty) .DoesNotExist() 'работает нормально как отметил @ haim770 в комментариях по этому вопросу. Вероятно, просто придерживайтесь проверки на нуль, хотя –

 Смежные вопросы

  • Нет связанных вопросов^_^