Zac*_*ott 4 c# object-initializers c#-4.0
假设您有一个Price对象接受(int数量,小数价格)或包含"4/$ 3.99"的字符串.有没有办法限制哪些属性可以设置在一起?请在下面的逻辑中随意纠正我.
测试:A和B彼此相等,但不允许使用C示例.因此,问题如何强制所有三个参数都不会像在C示例中那样被调用?
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
Run Code Online (Sandbox Code Playgroud)
班级:
public class AdPrice {
private int _qty;
private decimal _price;
private string _priceText;
Run Code Online (Sandbox Code Playgroud)
构造函数:
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; }
Run Code Online (Sandbox Code Playgroud)
方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
访问者:
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(); } }
}
Run Code Online (Sandbox Code Playgroud)
Jul*_*iet 11
嗯...而不是打击编译器,也许你只需要重新考虑你的API.你考虑过以下几点:
没有二传手.您的类应该是不可变的,因此它通过构造函数完全初始化,并且不能在无效状态下初始化.
如果您坚持使用setter,那么您的PriceText属性可以是只读的,而其他属性是可读/写的.至少在执行此操作时,您无需验证传递到该属性的文本.
也许完全删除PriceText属性,覆盖.ToString方法中对象的字符串表示形式.
在我看来,最后一个选项是最好的方法.我不认为用户应该将伪序列化字符串传递给您的类,因为它需要解析和验证 - 并且负担应该真正在使用您的类而不是您自己的类本身的客户端上.
对于字符串部分,最好有一个静态方法来解析字符串并返回一个Price实例.
例如
Price newPrice = Price.FromString("4/$3.99");
Console.WriteLine("{0} qty for {1}", newPrice.Quantity, newPrice.Price);
Run Code Online (Sandbox Code Playgroud)
这里FromString是静态方法.
这就像Enum.Parse你想看一个例子一样.
| 归档时间: |
|
| 查看次数: |
438 次 |
| 最近记录: |