【问题标题】:Expression Is a value and therefore cannot be the target of an assignmentExpression 是一个值,因此不能作为赋值的目标
【发布时间】:2010-10-15 10:51:14
【问题描述】:

我今天在使用结构时遇到了一个问题,让我措手不及,我希望有人能帮我解释一下。

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

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

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

【问题讨论】:

    标签: .net struct


    【解决方案1】:

    首先 - 没有可变结构(即,您可以在构造后通过设置器等更改值的结构)。这是造成混乱的主要原因。

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

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

    PaymentDetail 设为一个类;这是正确的解决方案......

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

    【讨论】:

    • 所以每次我更改其中一个值时,它都会清除结构中的其他值?
    • 不...只是你可能没有编辑你认为的PaymentDetail - 每次你眨眼它都会克隆自己!
    【解决方案2】:

    这可能是因为您将 Payment 公开为只读,而不是 setter。由于结构是值类型,如果结构是只读的,则不允许您在结构上设置属性。

    添加一个 setter 应该可以解决这个问题。

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

    【讨论】:

    • 添加一个 setter 并不能解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2018-03-28
    • 2018-09-05
    • 1970-01-01
    相关资源
    最近更新 更多