首页 > 解决方案 > 类层次结构,按优先级获取属性

问题描述

我有类层次结构。每个类都可能有配置对象。我需要得到最终配置——如果配置有第一类(A),它将被使用这个。如果配置有第二类(B),将使用这一类。

这是一个例子:

答:- C23

乙: - -

C :C2-

D:C1 C4

结果是 C.Config1.C2 和 A.Config2.C23。简而言之,我需要首先使用非空常量。这是我的代码:

enum Config { C1, C2, C3, C4 }

enum Config2 { C21, C22, C23, C24 }

class Configuration
{
    public Config Const1 { get; set; }
    public Config2 Const2 { get; set; }
}

class A
{
    public Configuration Config => CombineConfigs();

    public B B { get; set; }

    private Configuration CombineConfigs()
    {
        Config c1 = B.Config != null && B.Config.Const1 != null 
                    ? B.Config.Const1 
                    : B.C.Config != null && B.C.Config.Const1 != null 
                      ? B.C.Config.Const1 
                      : B.C.D.Config != null && B.C.D.Config.Const1 != null 
                        ? B.C.D.Config.Const1 
                        : Test.Config.C1;
        Config2 c2 = B.Config != null && B.Config.Const2 != null 
                     ? B.Config.Const2 
                     : B.C.Config != null && B.C.Config.Const2 != null 
                       ? B.C.Config.Const2 
                       : B.C.D.Config != null && B.C.D.Config.Const2 != null 
                         ? B.C.D.Config.Const2 
                         : Test.Config2.C21;
        return new Configuration()
        {
            Const1 = c1,
            Const2 = c2
        };
    }
}

class B
{
    public Configuration Config { get; set; }
    public C C { get; set; }
}

class C
{
    public Configuration Config { get; set; }
    public D D { get; set; }
}

class D
{
    public Configuration Config { get; set; }
}

如何写出更好的方法CombineConfigs

标签: c#

解决方案


这可能不是最好的方法,但您可以使用 null 合并运算符来取得很好的效果:

var c1 = B?.Config?.Const1 
         ?? B?.C?.Config?.Const1 
         ?? B?.C?.D?.Config?.Const1 
         ?? Test.Config.C1;

虽然如果我正确理解你的问题,你应该颠倒顺序;如果您想要最“衍生”的配置,只需执行以下操作:

var c1 = B?.C?.D?.Config?.Const1
         ?? B?.C?.Config?.Const1
         ?? B?.Config?.Const1
         ?? Test.Config.C1;

当然,这有点可怕,所以你可能想考虑一个不同的设计,特别是如果你不确定可能有多少“深度”。

另外,请记住,我放弃了您的等价物B.Config.Const1 != null- 这些将始终评估为真。如果您还想拥有 的选项,B.Config.Const1则需要将其声明为可空值 ( Config?)。枚举的旧方法也是使用保护值作为默认值,通常使用 value 0。两者都有其好处。


推荐阅读