Избегайте нулевой ссылки, используя возможности C # - PullRequest
3 голосов
/ 11 августа 2011

Я пытаюсь очистить метод большого обработчика, который показывает или нет метку на представлении.

Фактическая структура выглядит примерно так:

if (Moo.Foo != null) {
    Show(TrType, LabelType, Moo.Foo.DangerousNullRef + " - " + Moo.Foo.AnotherPossibleNullRef);
}
else {
    DontShowField(TrType);
}

Я думаюв чем-то вроде отправки всех компонентов, вовлеченных в метод, который делает все скучные вещи, но:

ShowHandlingNull(Moo.Foo != null, TrType, LabelType, Moo.Foo.DangerousNullRef + " - " + Moo.Foo.AnotherPossibleNullRef);

Будет вызывать нулевую ссылку, если Moo.Foo равен нулю.Могу ли я делегировать или ввести какое-то действие в одну большую строку моего большого метода?

Ответы [ 6 ]

1 голос
/ 11 августа 2011

Уже есть идея использовать Func для обработки этого, что мне кажется лучшим решением, я просто сделал несколько предположений относительно вашего намерения и предположил, что вы пытаетесь получить текст этой метки, поэтому я написал его как таковой.

   private void YourFunction
    {
        Type TrType = this.GetType();
        MooClass Moo = new MooClass();
        LabelTypeEnum LabelType = LabelTypeEnum.something;
        ShowIf(Moo, TrType, LabelType, new Object[] { Moo.Foo, Moo.Foo2, Moo.Foo3 }, a => a.Foo.DangerousNullRef + " - " + a.Foo.AnotherPossibleNullRef);

    }


    void ShowIf(MooClass Moo, Type t, LabelTypeEnum LabelType, IEnumerable<object> PreCheckNullsValues, Func<MooClass, string> mc )
    {
        if (PreCheckNullsValues.Any(a => a == null))
            Show(t, LabelType, mc(Moo));
        else
            DontShowField(t);
    }

Вот предполагаемый скелет вашего кода поддержки:

   enum LabelTypeEnum
    {
        something
    }

    class MooClass
    {
        public FooClass Foo { get; set; }
    }

    class FooClass
    {
        public object DangerousNullRef { get; set; }
        public object AnotherPossibleNullRef { get; set; }
    }

    private void Show(Type TrType, LabelTypeEnum LabelType, string p) { }

    private void DontShowField(Type TrType) { }

Затем вы можете использовать Действие для безопасного доступа к своим свойствам.

1 голос
/ 11 августа 2011

Вы можете следовать рекомендациям Null Object .

Например, Moo.Foo может стать интерфейсом, а реальный класс должен стать реализацией указанного интерфейса. Затем вы создаете класс MooFooNull, который обрабатывает случай, когда Foo имеет значение null, то есть метод DontShowField.

// On Moo.Foo initialization, if the condition for creating of RealMooFoo are not met.
Moo.Foo = new MooFooNull(this);

// later on ...
Moo.Foo.Show(TrType, LabelType, Moo.Foo.DangerousNullRef + " - " + Moo.Foo.AnotherPossibleNullRef);

где метод Show MooFooNull:

void Show(TheClass theClass, object trType, ... ) {
    theClass.DontShowField(trType);
}
1 голос
/ 11 августа 2011

Я бы не стал считать это улучшением, но это можно сделать с помощью отложенного выполнения через лямбда-выражения.

ShowHandlingNull(Moo.Foo, TrType, LabelType, f => f.DangerousNullRef, f => f.AnotherPossibleNullRef);

void ShowHandlingNull(Foo foo, object trType, objectLablelType, Func<Foo, object> dangerousNullRefGetter, Funct<Foo, object> anotherDangerousGetter)
{
    if (foo == null) {
        DontShowField(trType);
        return;
    }
    Show(TrType, LabelType, dangerousNullRefGetter(foo) + " - " + anotherDangerousGetter(foo));
}

Но я думаю, что ваш исходный if пустой тест легче понять и поддерживать.

0 голосов
/ 11 августа 2011

Используйте метод небольшого расширения:

public static class OrEmpty<T>(this T instance) where T : class, new()
{
    return instance ?? new T();
}

Пример:

Show(TrType, LabelType, Moo.Foo.OrEmpty().DangerousNullRef + " - " + Moo.Foo.OrEmpty().AnotherPossibleNullRef);

Обратите внимание, что для каждого вызова будет создан новый объект.Вы можете сделать его немного более продвинутым, чтобы избежать создания большого количества объектов.

0 голосов
/ 11 августа 2011

почему бы не попробовать и использовать метод расширения, который принимает ноль

public static string ShowHandlingNull(this Foo foo, TrType trType, LabelType labelType)
{
    if (foo == null)
    {
        return string.Empty;
    }
    return ......
}

var result = Moo.Foo.ShowHandlingNull(trType, labelType);
0 голосов
/ 11 августа 2011

Вы могли бы написать себе какой-нибудь метод, который действует как Strings "+" и проверяет нулевые ссылки (и добавляет его как метод расширения к строке), но я думаю, что это будет излишним.Просто измените / перегрузите ваш show-method параметром "Moo" (каким бы он ни был) и зарегистрируйтесь там.

...