C# C访问修饰符取决于状态

C# C访问修饰符取决于状态,c#,properties,C#,Properties,假设OrderAggregate类具有信用卡类作为属性。根据顺序状态,我想更改信用卡类属性的访问修饰符。例如:如果订单状态=Order.NewOrder,则允许修改信用卡属性,但是如果订单状态=Order.CompletedOrder,则我不希望允许设置信用卡中的属性 我希望能够在编译时和运行时进行检查 我想到的唯一解决方案是创建两个继承自同一父类的类;一个允许属性可设置而另一个不允许,但是如果存在一个状态要求某些属性可设置而另一些属性不可设置,那么它很快就会变得毛茸茸的 非常感谢您的任何想法。

假设OrderAggregate类具有信用卡类作为属性。根据顺序状态,我想更改信用卡类属性的访问修饰符。例如:如果订单状态=Order.NewOrder,则允许修改信用卡属性,但是如果订单状态=Order.CompletedOrder,则我不希望允许设置信用卡中的属性

我希望能够在编译时和运行时进行检查

我想到的唯一解决方案是创建两个继承自同一父类的类;一个允许属性可设置而另一个不允许,但是如果存在一个状态要求某些属性可设置而另一些属性不可设置,那么它很快就会变得毛茸茸的


非常感谢您的任何想法。

解决此问题的另一种方法是在第208-209页的“设计模式”中作为保护代理


为另一个对象提供代理项或占位符,以控制对该对象的访问。将对象的保护代理版本替换为实际对象,并且保护代理中的访问逻辑返回只读数据,但在尝试写入时进行检查。

解决此问题的另一种方法是将“设计模式”第208-209页作为保护代理


为另一个对象提供代理项或占位符,以控制对该对象的访问。您将对象的保护代理版本替换为实际对象,并且保护代理中的访问逻辑返回只读数据,但在尝试写入时进行检查。

我将使用两个不同的接口表示信用卡对象。一个是二传手,另一个是接球手。Order类上的CreditCard属性只能是getter接口

class CreditCardBase : ICreditCard 
{
    string Name { get; }
}

interface IWritableCreditCard : ICreditCard
{
    string Name { get; set; }
}

class WritableCreditCard : CreditCardBase, IWritableCreditCard {}

class Order
{
    private ICreditCard _card = new WritableCreditCard(); //initially...
    public ICreditCard Card { get {return _card; } }

    void OnComplete(...) { _card = new CreditCardBase(copy from _card); }
}
在运行时,将卡的属性强制转换到setter接口,以修改卡的属性。如果order状态现在处于只读状态,那么实现CreditCard的对象将与只实现getter的实现进行交换


我不知道如何在编译时进行区分,但至少正常的操作是安全的getter-only调用,修改代码将是一个丑陋且易于检测的代码,如果在错误的时间执行,b将返回null或throw。

我将用两个不同的接口表示信用卡对象。一个是二传手,另一个是接球手。Order类上的CreditCard属性只能是getter接口

class CreditCardBase : ICreditCard 
{
    string Name { get; }
}

interface IWritableCreditCard : ICreditCard
{
    string Name { get; set; }
}

class WritableCreditCard : CreditCardBase, IWritableCreditCard {}

class Order
{
    private ICreditCard _card = new WritableCreditCard(); //initially...
    public ICreditCard Card { get {return _card; } }

    void OnComplete(...) { _card = new CreditCardBase(copy from _card); }
}
在运行时,将卡的属性强制转换到setter接口,以修改卡的属性。如果order状态现在处于只读状态,那么实现CreditCard的对象将与只实现getter的实现进行交换


我不知道如何在编译时进行区分,但至少正常操作是安全的getter-only调用,修改代码将是一个丑陋且易于检测的代码,如果在错误的时间执行,b将返回null或抛出。

您如何设想此工作的编译时解决方案?他将编写自己的VS扩展。是的,创建2个静态类是实现编译时检查的方法。然而,我仍然支持使用一个类并抛出运行时“OperationNotAllowed”类错误;您将为一种类型复制代码/同步/维护两个类。我在codeproject上找到了一个解决方案。我记不起将修改属性的链接是MSIL。这是我们在头脑风暴状态和存储库框架时提出的。您如何设想编译时解决方案?他将编写自己的VS扩展。是的,创建两个静态类是实现编译时检查的方法。然而,我仍然支持使用一个类并抛出运行时“OperationNotAllowed”类错误;您将为一种类型复制代码/同步/维护两个类。我在codeproject上找到了一个解决方案。我记不起将修改属性的链接是MSIL。这是我们在头脑风暴状态和存储库框架时提出的。这与我的想法类似,只是我会使用一个只有getter和所有支持字段的类,使其为只读,这样属性只能在实例化时设置。如果有必要更改,我将创建一个新实例,将所有现有属性+更改复制到新实例中。@Daver:不认为您可以用表示WritableCreditCard类的方式更新示例吗?我想不出你会怎么做,因为new将应用于继承的属性get,但是没有设置为new。在重写访问器时,使其虚拟化也会失败。这与我的想法类似,只是我会使用一个只有getter和所有支持字段的类,使其为只读,以便只能在实例化时设置属性。如果需要更改,我将创建一个新实例,将所有现有属性+更改复制到新实例中。@Daver:不要认为您可以更新
请举例说明如何表示WritableCreditCard类?我想不出你会怎么做,因为new将应用于继承的属性get,但是没有设置为new。在重写访问器时,将其虚拟化也会失败。您希望编译时检查与运行时检查的原因是,您不希望使用业务对象的开发人员执行设置,即Order.CreditCard.Number=。。。然后发现当抛出异常时,它们不能。对象的设计应始终确保开发人员不需要知道如何运行IsChangeAllowed等。对象的设计应始终确保开发人员不需要知道如何运行IsChangeAllowed,这取决于您尝试创建的内容。我不是想暗示开发人员必须运行检查,我只是想了解您的问题。此解决方案的问题是,如果IsWritable=false,集合将运行,用户无法直观地知道它没有正确设置的原因。我同意traderde的观点,这种行为将是混乱和隐藏的。公共接口的行为应该始终与您期望的一样—抛出异常或忽略输入会让许多用户措手不及。不幸的是,我不知道如何使编译时工作。我认为您可以尝试使使用尽可能简单,比如2个卡片属性,它们向底层数据返回只读和可写接口?这取决于具体情况。抛出异常或忽略输入并不一定是错误的,如果这是项目需求所指定的,或者团队有任何一组通用约定的话。编译时检查以及在此上下文中如何定义编译时检查是不寻常的,因此我感觉traderde正在寻求一种不那么优雅的解决方案。这就是我鼓励他提供更多细节的原因。您希望编译时检查与运行时检查的原因是因为您不希望使用业务对象的开发人员执行一组操作,即Order.CreditCard.Number=。。。然后发现当抛出异常时,它们不能。对象的设计应始终确保开发人员不需要知道如何运行IsChangeAllowed等。对象的设计应始终确保开发人员不需要知道如何运行IsChangeAllowed,这取决于您尝试创建的内容。我不是想暗示开发人员必须运行检查,我只是想了解您的问题。此解决方案的问题是,如果IsWritable=false,集合将运行,用户无法直观地知道它没有正确设置的原因。我同意traderde的观点,这种行为将是混乱和隐藏的。公共接口的行为应该始终与您期望的一样—抛出异常或忽略输入会让许多用户措手不及。不幸的是,我不知道如何使编译时工作。我认为您可以尝试使使用尽可能简单,比如2个卡片属性,它们向底层数据返回只读和可写接口?这取决于具体情况。抛出异常或忽略输入并不一定是错误的,如果这是项目需求所指定的,或者团队有任何一组通用约定的话。编译时检查以及在此上下文中如何定义编译时检查是不寻常的,因此我感觉traderde正在寻求一种不那么优雅的解决方案。这就是为什么我要鼓励他提供更多细节。