我今天遇到一个使用结构的问题让我措手不及,我希望有人可以为我解释一下。
我有一个像这样定义的结构:
public struct PaymentDetail
{
public Decimal Amount{get;set;}
public string CheckNumber{get;set;}
public PaymentType PaymentType{get;set;}
}
我有一个包含此信息的课程
public class Transaction
{
public PaymentDetail Payment{get;}
}
我有一个演示模型,我想在其中设置像这样的基础属性
public class ViewModel
{
public Decimal Amount
{
get{return _Transaction.PaymentDetail.Amount;}
set
{
//This is the offending line of code
_Transaction.PaymentDetail.Amount = value;
RaisePropertyChanged("Amount");
}
}
}
如果我将Payment属性更改为这样的公共字段,我可以做到这一点很奇怪:
public class Transaction
{
public PaymentDetail Payment;
}
有一些我不明白的结构导致这种情况。这是一个坏主意吗?有没有更好的办法?我做错了什么?
答案 0 :(得分:6)
首先 - 没有可变结构(即可以在构造之后通过setter等更改值的结构)。这是造成混淆的主要原因。
重点是;当您调用某个属性(例如Payment
)时,您会获得该值的副本(在您的本地堆栈区域中)。对于一个类,这是一个引用的副本(没问题)。对于结构体,它是结构本身的副本。对该值的任何更改都将被丢弃,因此编译器已阻止您丢失数据。
当它是一个公共字段时,你正在直接改变原始值,这就是它不介意的原因。但改变结构确实不是一个好主意。
让PaymentDetail
成为一个班级;这是正确的解决方案......
在.NET中,结构体不是“没有行为的对象” - 它们是“价值类型”。诸如“货币/价值对”,“时间范围”等等可能会产生有效的结构 - 但不是PaymentDetail
。
答案 1 :(得分:-3)
可能是因为您将付款视为只读,没有制定者。由于struct是一个value-type,如果struct是readonly,它将不允许你在struct上设置一个属性。
添加setter应解决问题。
我还会考虑将PaymentDetail更改为一个班级。当它是一个非常基本的值时,我只使用结构。像这样的三个属性的东西,特别是如果一个是字符串应该是一个类。