Say you have a Price object that accepts either an (int quantity, decimal price) or a string containing "4/$3.99". Is there a way to limit which properties can be set together? Feel free to correct me in my logic below.
The Test: A and B are equal to each other, but the C example should not be allowed. Thus the question How to enforce that all three parameters are not invoked as in the C example?
AdPrice A = new AdPrice { priceText = "4/$3.99"}; // Valid
AdPrice B = new AdPrice { qty = 4, price = 3.99m}; // Valid
AdPrice C = new AdPrice { qty = 4, priceText = "2/$1.99", price = 3.99m};// Not
The class:
public class AdPrice {
private int _qty;
private decimal _price;
private string _priceText;
The constructors:
public AdPrice () : this( qty: 0, price: 0.0m) {} // Default Constructor
public AdPrice (int qty = 0, decimal price = 0.0m) { // Numbers only
this.qty = qty;
this.price = price; }
public AdPrice (string priceText = "0/$0.00") { // String only
this.priceText = priceText; }
The Methods:
private void SetPriceValues() {
var matches = Regex.Match(_priceText,
@"^\s?((?<qty>\d+)\s?/)?\s?[$]?\s?(?<price>[0-9]?\.?[0-9]?[0-9]?)");
if( matches.Success) {
if (!Decimal.TryParse(matches.Groups["price"].Value,
out this._price))
this._price = 0.0m;
if (!Int32.TryParse(matches.Groups["qty"].Value,
out this._qty))
this._qty = (this._price > 0 ? 1 : 0);
else
if (this._price > 0 && this._qty == 0)
this._qty = 1;
} }
private void SetPriceString() {
this._priceText = (this._qty > 1 ?
this._qty.ToString() + '/' : "") +
String.Format("{0:C}",this.price);
}
The Accessors:
public int qty {
get { return this._qty; }
set { this._qty = value; this.SetPriceString(); } }
public decimal price {
get { return this._price; }
set { this._price = value; this.SetPriceString(); } }
public string priceText {
get { return this._priceText; }
set { this._priceText = value; this.SetPriceValues(); } }
}