简体   繁体   English

C#依赖属性,依赖于setter执行的正确顺序

[英]C# Dependent properties, dependency on correct order of setter execution

I wonder how to deal with dependent properties in C#. 我想知道如何处理C#中的依赖属性。 I have following simplified classes (I'm using DevExpress XAF ): 我有以下简化的类(我正在使用DevExpress XAF ):

public class Company
{
    public ContactMethods? PreferredContactMethod { get; set; }
    // Missing: Collection of Employees...
}

public class Employee
{
    private Company company;

    public Company Company
    {
        get
        {
            return this.company;
        }
        set
        {
            company = value;
            if (company != null && PreferredContactMethod == null)
            {
                PreferredContactMethod = company.PreferredContactMethod;
            }
        }
    }

    public ContactMethods? PreferredContactMethod { get; set; }
}

When assigning a Company to an Employee, I set the Employee.PreferredContactMethod to the PreferredContactMethod of the Company (just for convenience, can be changed later). 将公司分配给员工时,我将Employee.PreferredContactMethod设置为公司的PreferredContactMethod(为方便起见,以后可以更改)。


Update: 更新:

I want to use the Company.PreferredContactMethod just as a default value when initializing new Employees. 我想在初始化新员工时将Company.PreferredContactMethod用作默认值。 Every Employee stores its own ContactMethod independently from the Company. 每个员工都独立于公司存储自己的ContactMethod。 Later changes to the Company.PreferredContactMethod shouldn't update the Employee.PreferredContactMethod. 以后对Company.PreferredContactMethod的更改不应更新Employee.PreferredContactMethod。 It is perfectly legal for the Employee.PreferredContactMethod to be null (eg if explicitly set be user). Employee.PreferredContactMethod为null是完全合法的(例如,如果显式设置为user)。


Quite simple code and of course this is just working fine. 非常简单的代码,当然这很好。 But I think it violates Microsoft's Property Design Guidelines : 但是我认为这违反了Microsoft的《财产设计指南》

Do allow properties to be set in any order even if this results in a temporary invalid object state. 允许以任何顺序设置属性,即使这会导致临时无效的对象状态。

Company = A, PreferredContactMethod = null gives another result than PreferredContactMethod = null, Company = A . Company = A, PreferredContactMethod = null给出另一个结果,而不是PreferredContactMethod = null, Company = A

I think I cannot rely on a 'correct' order of the property setters (eg if using Automapper/Reflection), How do you deal with such a situation? 我认为我不能依靠属性设置器的“正确”顺序(例如,如果使用Automapper / Reflection),您如何处理这种情况? I think it's not uncommon. 我认为这并不少见。

Thank you! 谢谢!

You want to ensure the invariant that the Employee's has the same PreferredContactMethod as this Company himself, unless he has a specified PreferredContancMethod himself. 您要确保不改变雇员与该公司本人具有相同的PreferredContactMethod,除非他本人具有指定的PreferredContancMethod。 One way, extending your solution, is to implement this is to update this value like this: 扩展您的解决方案的一种方法是实施此方法,以像这样更新此值:

public class Employee
{
    private Company company;
    public Company Company
    {
        get { return this.company; }
        set
        {
            this.company = value;
            UpdateCompanyPreferredContactMethod();
        }
    }

    private ContactMethods? preferredContactMethod;
    public ContactMethods? PreferredContactMethod 
    {
        get { return this.preferredContactMethod; }
        set
        {
            this.preferredContactMethod = value;
            UpdateCompanyPreferredContactMethod();
        }
    }

    private void UpdateCompanyPreferredContactMethod()
    {
        if (PreferredContactMethod == null)
        {
            PreferredContactMethod = company != null ?company.PreferredContactMethod : null;
        }
    }
}

However, this solution is fragile, as you have to update this value every time you change either. 但是,此解决方案非常脆弱,因为每次更改其中一个值时都必须更新此值。 Instead, I would actually do something like this: 相反,我实际上会这样做:

public class Employee
{
    public Company Company { get; set; }

    private ContactMethods? preferredContactMethod;
    public ContactMethods? PreferredContactMethod 
    {
        get 
        { 
            if (this.preferredContactMethod != null)
            {
                return this.preferredContactMethod;
            }
            else if (this.Company != null)
            {
                return this.Company.PreferredContactMethod;
            }
            else
            {
                return null;
            }
        }
        set { this.preferredContactMethod = value; }
    }
}

You say you want to use the PreferredContactMethod as default value when initializing a new Employee. 您说要在初始化新Employee时将PreferredContactMethod用作默认值。 If this is the case, you should pass the Company to the constructor of the Employee, and set it then: 在这种情况下,您应该将Company传递给Employee的构造函数,然后进行设置:

public Employee(Company company) {
    // Null checks as appropriate
    this.company = company;
    this.PreferredContactMethod = company.PreferredContactMethod;
}

If you also want to change the PreferredContactMethod the way you do, and your only concern is violating the design guidelines, then maybe use a method Employee.SetCompany to indicate that the operation has side effects in addition to just changing the Company property. 如果您还想按照自己的方式更改PreferredContactMethod,而您唯一的担心是违反了设计准则,则可以使用Employee.SetCompany方法来表明该操作除了更改Company属性之外还具有副作用。

I think you need to assign it just before when saving the Employee object therefore any order gives the same result. 我认为您需要在保存Employee对象之前分配它,因此任何顺序都可以得到相同的结果。

try this; 尝试这个;

if (IsNewRecord && Company != null && PreferredContactMethod == null)
    PreferredContactMethod = Company.PreferredContactMethod;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM