С# null цепочка проверки в вызове метода
Я предполагаю, что цепочка вызовов метода ниже.
void DoSomething()
{
ObjectA a = CreateA();
if (a != null)
{
a.Foo();
}
}
ObjectA CreateA()
{
ObjectB b = CreateB();
if (b != null)
{
ObjectA a = b.ToA();
return a;
}
return null;
}
Если глубина вызова метода будет глубже, проверка нуля будет более наложенной. Есть ли хорошее решение для этого?
Modified
Я изменил пример кода. Он не может решить мою проблему, которая меняет CreateA на конструктор. Проблема в том, что перекрытие нулевой проверки не является нулевым.
void SetImage()
{
UISprite image = GetSprite();
if (image != null)
{
image.spriteName = "hat";
}
}
UISprite GetSprite()
{
UISprite image = GetComponent<UISprite>();
if (image != null)
{
image.width = 100;
image.height = 100;
return image;
}
return null;
}
Начиная с С# 6.0 вы можете использовать Null-Conditional Operator, который позволяет делать нечетные проверки:
var result = possiblyNull?.MethodThatCanReturnNull()?.SomeProperty;
Эта конструкция создаст результат null
, если любой элемент в цепочке произведет null
.
Вы можете сделать
void DoSomething()
{
CreateA()?.Foo();
}
ObjectA CreateA()
{
return CreateB()?.ToA();
}
Ваш другой подход, если вы не можете использовать С# 6, не возвращает nulls, использует пустые объекты таким образом, чтобы вам никогда не приходилось иметь дело с нулевой проверкой (но вы все еще можете проверить, является ли что-то нулевым объектом)
Если вы используете С# 6.0 или выше, у вас есть простое решение с условными операторами Null для этой проблемы.
см. эту ссылку
Итак, если вы (или кто-то еще) не можете использовать оператор с нулевым условием, есть ли веская причина использовать этот шаблон методов, создающих объекты вместо конструкторов, создающих объекты? Конструкторы гарантированно не возвращают null.
Похоже, что у вас есть конверсия или иерархия вложенных объектов, но нет наследственной иерархии, где вы могли бы просто вернуться к полиморфизму. Может быть, инструмент, такой как AutoMapper, может быть полезен для последовательного кодирования этих методов ToX()?
Я не уверен, как это было бы "вложенным". Ваш метод CreateB() будет выглядеть точно так же, как ваш код CreateA(). Вы не получите в итоге "пирамиды" всего лишь много одинаковых методов.
ObjectB CreateB()
{
ObjectC c = CreateC();
if (c != null)
{
ObjectB b = c.ToB();
return b;
}
return null;
}
В большинстве случаев вы делаете это в среде, где вы не контролируете все классы. В этом случае наилучшим подходом является написание собственных функций преобразования или AutoMapper (действительно, стоит того времени). Но, если у вас есть иерархия классов, вы можете реализовать абстрактный класс, который сделает большую часть тяжелой работы для вас. Но, честно говоря, я бы написал только что-то подобное, если бы у меня была действительно веская причина (что-то большее, чем просто хотелось трахаться с людьми). Я включаю это, чтобы продемонстрировать, насколько проще жизнь, если вы просто используете конструктор, который гарантированно не возвращает null;
public abstract class MyAbstractObject<Tobj> where TObj: MyAbstractObject, new()
{
public static MyAbstractObject CreateObject()
{
Tobj subOb = new TObj();
MyAbstractObject parent = subOb.ToObject();
return parent;
}
public virtual TObj ToObject()
{
return CreateObject();
}
}
public class ObjectD : MyAbstractObject<ObjectC> { }
public class ObjectC : MyAbstractObject<ObjectB> { }
public class ObjectB : MyAbstractObject<ObjectA> { }
public class ObjectA : MyAbstractObject<ObjectA>
{
public override TObj ToObject()
{
return this;
}
}
static void Main()
{
ObjectA a = ObjectD.CreateObject();
}
Посмотрите другие вопросы по меткам c# null-check или Задайте вопрос