使用c#可能性避免空引用

时间:2011-08-11 13:50:30

标签: c# delegates code-cleanup

我正在尝试清理一个显示或不显示视图标签的大型处理程序方法。

实际结构如下:

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为null,将导致空引用。我可以委托或执行一些操作行为,并在我的大方法中只放一行吗?

6 个答案:

答案 0 :(得分:1)

我不认为这是一种改进,但可以通过lambda的延迟执行来完成。

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 null检查更容易理解和维护。

答案 1 :(得分:1)

您可以遵循Null Object pattern指南。

例如,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);

MooFooNull的Show方法是:

void Show(TheClass theClass, object trType, ... ) {
    theClass.DontShowField(trType);
}

答案 2 :(得分:1)

已经有了使用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) { }

然后,您可以使用操作安全地访问您的属性。

答案 3 :(得分:0)

你可以自己编写一些类似于字符串“+”的方法并检查null-References(并将其作为扩展方法添加到字符串中),但我认为这样会有点过分。 只需使用“Moo”(无论类型可能是什么)参数更改/重载show-method并在那里签入。

答案 4 :(得分:0)

为什么不尝试使用接受null的扩展方法

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

答案 5 :(得分:0)

使用小扩展方法:

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

请注意,它将为每次调用创建一个新对象。您可以使其稍微提高一些,以避免创建大量对象。