Что делает знак вопроса и точечный оператор?. означает в С# 6.0?
С С# 6.0 в предварительном просмотре VS2015 у нас есть новый оператор ?.
, который можно использовать следующим образом:
public class A {
string PropertyOfA { get; set; }
}
...
var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
//somecode
}
Что именно он делает?
Ответы
Ответ 1
Это нулевой условный оператор. Это в основном означает:
"Оценить первый операнд; если этот ноль, остановить, с результатом ноль. В противном случае, оценить второй операнд (как член доступа первого операнда)."
В вашем примере, суть в том, что если a
равно null
, то a?.PropertyOfA
будет оценивать как null
а не как исключение - тогда он будет сравнивать эту null
ссылку с foo
(используя строку ==
перегрузка) и обнаружит, что они не являются равный и выполнение войдет в тело оператора if
.
Другими словами, это так:
string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
...
}
... за исключением того, что a
оценивается только один раз.
Обратите внимание, что это также может изменить тип выражения. Например, рассмотрим FileInfo.Length
. Это свойство типа long
, но если вы используете его с условным оператором null, вы получите выражение типа long?
:
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
Ответ 2
Это может быть очень полезно при выравнивании иерархии и/или отображении объектов. Вместо:
if (Model.Model2 == null
|| Model.Model2.Model3 == null
|| Model.Model2.Model3.Model4 == null
|| Model.Model2.Model3.Model4.Name == null)
{
mapped.Name = "N/A"
}
else
{
mapped.Name = Model.Model2.Model3.Model4.Name;
}
Это может быть написано как (та же логика, что и выше)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
DotNetFiddle.Net Рабочий пример.
(Оператор?? или null-coalescing отличается от оператора ? или null).
Его также можно использовать вне операторов присваивания с действием. Вместо
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
Это может быть упрощено до:
myAction?.Invoke(TValue);
Пример DotNetFiddle:
используя Систему;
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
Результат:
Тест 2
Ответ 3
Это относительно новое для С#, что позволяет нам легко вызывать функции с нулевыми или ненулевыми значениями в цепочке методов.
Старый способ добиться того же был:
var functionCaller = this.member;
if (functionCaller!= null)
functionCaller.someFunction(var someParam);
и теперь это стало намного проще с помощью просто:
member?.someFunction(var someParam);
Я настоятельно рекомендую вам прочитать это здесь:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
Ответ 4
Другим способом это можно использовать для операторов in-line if:
lblDueDate.Text =
assignment.DueDate == null ? "" : (assignment.DueDate.Value.ToShortDateString());
Выход
lblDueDate = 12/21/2021
Вместо:
if(assignment.DueDate == null)
{
lblDueDate.Text = "";
}
else
{
lblDueDate.Text = assignment.DueDate.ToShortDateString();
}
FYI .ToShortDateString()
просто выравнивает раздражающее время с конца возвращаемого значения DateTime
. Вместо 12/21/2021 05:20:00.655