We have a message that is being passed to a method.
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
}
}
Can't check if IsCredit was forgotten to be assigned of value, as unassigned boolean defaults to false, which means it's a Debit, an assignment of IsCredit = false;
could not be detected as unassigned, as it indicates a Debit instead.
So I suggested to use a DrCrFlag which starts with value of 1.
public enum DrCrFlag
{
Debit = 1,
Credit = 2
}
That way, the DoSomething method can have a guard clause that checks if message's IsCredit property is forgotten to be assigned just by checking if the enum is zero.
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");
}
However, the the data contract could be broken on those client apps that rely on boolean property. So changing boolean to DrCrFlag is not possible.
So then I suggested to use a nullable boolean, which could also break existing client app, but they welcome changing the boolean to nullable boolean more than the changing of boolean to enum.
This can be implemented:
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");
}
Is this the right way to guard against unassigned variable?
Should all actions validate the values being passed to it?