C# 可能忘记指定值的属性的Guard子句

C# 可能忘记指定值的属性的Guard子句,c#,enums,guard-clause,C#,Enums,Guard Clause,我们有一条消息正在传递给一个方法 class Message { public int TransactionId { get; set; } public bool IsCredit { get; set; } // Debit when false public decimal Amount { get; set; } } class ServiceBus { public IService TheSe

我们有一条消息正在传递给一个方法

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,这意味着它是借方,赋值为
IsCredit=false无法检测为未分配,因为它指示借方

所以我建议使用以值1开头的a

public enum DrCrFlag 
{
    Debit  = 1,
    Credit = 2
}
这样,DoSomething方法就可以有一个检查是否忘记分配消息的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是不可能的

因此,我建议使用一个可为null的布尔值,这也可能破坏现有的客户端应用程序,但他们更欢迎将布尔值更改为可为null的布尔值,而不是将布尔值更改为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
类型。

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