用于可能忘记为属性赋值的保护子句

本文关键字:赋值 保护 子句 属性 记为 忘记 用于 | 更新日期: 2023-09-27 18:01:37

我们有一个传递给方法的消息。

class Message
{
    public int     TransactionId    { get; set; }
    public bool    IsCredit         { get; set; } // Debit when false
    public decimal Amount           { get; set; }
}
class ServiceBus
{
    public IService TheService { get; set; }
    public void SomethingHappen()
    {       
        var message = new Message
        {
            TransactionId = 7,
            Amount        = 6
            // forgot to assign IsCredit
        };
        TheService.DoSomething(message);
    }
}
class Service
{
    public void DoSomething(Message message)
    {
        // Before proceeding with anything else, wanted to put 
        // a guard clause if something was not assigned, e.g., IsCredit             
    }
}

无法检查IsCredit是否忘记赋值,因为未赋值的布尔值默认为false,这意味着它是一个Debit, IsCredit = false;的赋值不能被检测为未赋值,因为它指示的是Debit。

所以我建议使用DrCrFlag,它以1的值开始。

public enum DrCrFlag 
{
    Debit  = 1,
    Credit = 2
}

这样,DoSomething方法就可以有一个保护子句,通过检查enum是否为零来检查消息的IsCredit属性是否忘记分配。

public void DoSomething(Message message)
{
    // Before proceeding with anything else, wanted to put 
    // a guard clause if something was forgotten to be assigned, e.g., IsCredit             
    if (message.DrCrFlag == 0) throw new ArgumentException("DrCrFlag is unassigned");
}

然而,在那些依赖布尔属性的客户端应用程序上,数据契约可能被破坏。因此,将布尔值更改为DrCrFlag是不可能的。

所以我建议使用一个可空的布尔值,这也可能会破坏现有的客户端应用程序,但他们欢迎将布尔值更改为可空的布尔值,而不是将布尔值更改为enum。

这可以实现:

class Message
{
    public int     TransactionId    { get; set; }
    public bool?   IsCredit         { get; set; } // Debit when false
    public decimal Amount           { get; set; }
}
public void DoSomething(Message message)
{
    // Before proceeding with anything else, wanted to put 
    // a guard clause if something was forgotten to be assigned, e.g., IsCredit             
    if (message.IsCredit == null) throw new ArgumentException("IsCredit is unassigned");
}

这是防止未赋值变量的正确方法吗?

所有的动作都应该验证传递给它的值吗?

用于可能忘记为属性赋值的保护子句

另一种方法是声明类型为bool?的私有成员mIsCredit。然后在getter中,您可以检查私有变量的值,如果它是null则抛出异常。这样,您的公共属性将保持bool类型。