Цепочка нулевой проверки C # при вызове метода

Я предполагаю цепочку вызовов методов ниже.

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;
}

Если глубина вызова метода станет больше, проверка на null будет более перекрываться. Есть ли для этого хорошее решение?

Изменено

Я изменил пример кода. Это не может решить мою проблему с изменением 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;
}

person seung hwan Son    schedule 31.03.2017    source источник
comment
Вы можете изучить оператор C # 6 с условием NULL msdn.microsoft.com /en-us/library/dn986595.aspx   -  person Nelson    schedule 31.03.2017
comment
Возможный дубликат Уникальные способы использования оператора Null Coalescing   -  person khargoosh    schedule 31.03.2017
comment
Я думаю, @Nelson C # 3.0. (Используйте Unity 5.4)   -  person seung hwan Son    schedule 31.03.2017


Ответы (4)


Начиная с C # 6.0 вы можете использовать Null- Условный оператор, который позволяет неявно проверять значение NULL:

var result = possiblyNull?.MethodThatCanReturnNull()?.SomeProperty;

Эта конструкция даст результат null, если какой-либо элемент в цепочке выдаст null.

person Sergey Kalinichenko    schedule 31.03.2017
comment
Прости. Я программист игр с Unity Engine. Он по-прежнему использует Mono v2.6. - person seung hwan Son; 31.03.2017

Ты можешь сделать

void DoSomething()
{
    CreateA()?.Foo();
}

ObjectA CreateA()
{
    return CreateB()?.ToA();
}

Другой ваш подход, если вы не можете использовать С # 6, - это не возвращать значения NULL, использовать нулевые объекты таким образом, чтобы вам никогда не приходилось иметь дело с нулевой проверкой (но вы все равно можете проверить, является ли что-то нулевым объектом)

person Keith Nicholas    schedule 31.03.2017
comment
К сожалению, моя среда разработки - C # 3.0. - person seung hwan Son; 31.03.2017

Если вы используете C # 6.0 или выше, у вас есть простое решение с условными операторами Null для этой проблемы.

см. эту ссылку

https://msdn.microsoft.com/en-au/library/dn986595.aspx?f=255&MSPPError=-2147217396&cs-save-lang=1&cs-lang=csharp#code-snippet-1

person Santhosh    schedule 31.03.2017

Итак, предполагая, что вы (или кто-то еще) не можете использовать условный оператор 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();
}
person Michael Blackburn    schedule 31.03.2017
comment
Я надеюсь, что это утверждение об этой конкретной ситуации, а не общее утверждение о полезности шаблонов проектирования. - person Michael Blackburn; 31.03.2017
comment
Есть ли веская причина, по которой вы не используете конструктор, который гарантированно не имеет значения NULL? - person Michael Blackburn; 02.04.2017