3

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

实际的结构是这样的:

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

4

6 回答 6

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) { }

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

于 2011-08-11T14:37:33.867 回答
1

您可以遵循空对象模式指南。

例如,Moo.Foo 可以成为一个接口,而实际的类应该成为该接口的一个实现。然后创建一个 MooFooNull 类来处理 Foo 为空的情况,即 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);
}
于 2011-08-11T14:09:42.107 回答
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空检查更容易理解和维护。

于 2011-08-11T13:56:09.613 回答
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);

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

于 2011-08-11T14:07:22.713 回答
0

您可以为自己编写一些类似于字符串“+”的方法并检查空引用(并将其作为扩展方法添加到字符串中),但我认为这太过分了。只需使用“Moo”(无论类型如何)参数更改/重载您的显示方法并在那里检查。

于 2011-08-11T13:58:08.837 回答
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);
于 2011-08-11T14:00:11.580 回答