【问题标题】:Interdependent properties within a class类中相互依赖的属性
【发布时间】:2014-01-02 12:39:55
【问题描述】:

我有以下类可以改变某个查询的结果:

public class UniversalPrincipalQueryOptions
{
    public Boolean IncludeProperties { get; set; }
    public Boolean IncludeOrganizationUnits { get; set; }
    public Boolean IncludeManagers { get; set; }

    public static UniversalPrincipalQueryOptions All
    {
        get
        {
            return new UniversalPrincipalQueryOptions { IncludeOrganizationUnits = true, IncludeProperties = true, IncludeManagers = true };
        }
    }

    public static UniversalPrincipalQueryOptions None
    {
        get
        {
            return new UniversalPrincipalQueryOptions { IncludeProperties = false };
        }
    }

    public UniversalPrincipalQueryOptions()
    {
        this.IncludeProperties = true;
    }
}

问题是,当IncludePropertiesfalse 时将IncludeOrganizationUnits 设置为true 在我的情况下没有意义,IncludeManagers 也是如此,这也取决于将IncludeOrganizationUnits 设置为true .

我认为这不是最好的方法。所以我的问题是,我可以使用什么模式来改进这个类并让其他人更容易使用我的类?

更新:

好的,所以我最终切换到使用 Flags 属性装饰的 enum

[Flags]
public enum UniversalPrincipalQueryOptions
{
    None = 0,
    IncludeProperties = 1,
    IncludeOrganizationUnits = 2 | IncludeProperties,
    IncludeManagers = 4 | IncludeOrganizationUnits
}

【问题讨论】:

  • "true-ish" 在 javascript 中是有意义的(通常被称为truthy),但 true-ish 对 c# 布尔值意味着什么??
  • 你的问题是什么?
  • 不是答案:但这种跨规则强制执行是 CodeContract 库示例使用的常用示例。
  • @ken2k:我已经更新了帖子,并在最后包含了我的问题。
  • @Kassem 您的方案是否需要用户可以设置布尔值之一的值?

标签: c# .net class properties


【解决方案1】:

简单的答案是验证值而不是纯自动属性:

public Boolean IncludeProperties { get; set; }

private Boolean includeOrganizationUnits;
public Boolean IncludeOrganizationUnits 
{ 
    get { return this.includeOrganizationUnits }
    set
    {
        if(value && !IncludeProperties)
            throw new InvalidOperationException("IncludeProperties must be true when IncludeOrganizationUnits is set to true");
        includeOrganizationUnits = value;
    }
}

这种前置条件也可以使用CodeContracts 进行配置,但请注意performance hit by doing so

如果用户实际上不需要自己设置这些布尔值,则另一种选择是扩展您的静态列表以包含所有(有效)可能性并将事情设为私有(如 setter 和 ctor):

public class UniversalPrincipalQueryOptions
{
    public Boolean IncludeProperties { get; private set; }
    public Boolean IncludeOrganizationUnits { get; private set; }
    public Boolean IncludeManagers { get; private set; }

    // UPDATED !!
    public static UniversalPrincipalQueryOptions OrganizationUnitsAndManagers
    {
        get
        {
            return new UniversalPrincipalQueryOptions { IncludeOrganizationUnits = true, IncludeProperties = true, IncludeManagers = true };
        }
    }

    // NEW!!
    public static UniversalPrincipalQueryOptions OrganizationUnits
    {
        get
        {
            return new UniversalPrincipalQueryOptions { IncludeOrganizationUnits = true, IncludeProperties = true};
        }
    }

    public static UniversalPrincipalQueryOptions None
    {
        get
        {
            return new UniversalPrincipalQueryOptions { IncludeProperties = false };
        }
    }

    private UniversalPrincipalQueryOptions()
    {
        this.IncludeProperties = true;
    }
}

【讨论】:

  • 如果用户不需要设置属性的值,那么私有构造函数是可行的方法。
  • @ken2k - 你的意思是像我放在课堂上的私有构造函数?
  • 是的,完全正确(但我们仍然不确定这是 OP 的用例)
  • 其实我更喜欢第二个选项。你认为enum 更适合这个吗?
  • @Kassem - 枚举是另一种选择,可能带有Flags 属性。但您仍需要进行一些验证以确保设置了正确的组合。
猜你喜欢
  • 2016-04-13
  • 2013-07-19
  • 2013-08-04
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
相关资源
最近更新 更多