表达式是一个值,因此不能成为赋值的目标

时间:2009-03-25 13:00:20

标签: .net struct

我今天遇到一个使用结构的问题让我措手不及,我希望有人可以为我解释一下。

我有一个像这样定义的结构:

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;
}

有一些我不明白的结构导致这种情况。这是一个坏主意吗?有没有更好的办法?我做错了什么?

2 个答案:

答案 0 :(得分:6)

首先 - 没有可变结构(即可以在构造之后通过setter等更改值的结构)。这是造成混淆的主要原因。

重点是;当您调用某个属性(例如Payment)时,您会获得该值的副本(在您的本地堆栈区域中)。对于一个类,这是一个引用的副本(没问题)。对于结构体,它是结构本身的副本。对该值的任何更改都将被丢弃,因此编译器已阻止您丢失数据。

当它是一个公共字段时,你正在直接改变原始值,这就是它不介意的原因。但改变结构确实不是一个好主意。

PaymentDetail成为一个班级;这是正确的解决方案......

在.NET中,结构体不是“没有行为的对象” - 它们是“价值类型”。诸如“货币/价值对”,“时间范围”等等可能会产生有效的结构 - 但不是PaymentDetail

答案 1 :(得分:-3)

可能是因为您将付款视为只读,没有制定者。由于struct是一个value-type,如果struct是readonly,它将不允许你在struct上设置一个属性。

添加setter应解决问题。

我还会考虑将PaymentDetail更改为一个班级。当它是一个非常基本的值时,我只使用结构。像这样的三个属性的东西,特别是如果一个是字符串应该是一个类。