2

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

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

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

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

4

2 回答 2

6

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

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

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

上课PaymentDetail;这是正确的解决方案......

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

于 2009-03-25T13:02:47.650 回答
-3

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

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

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

于 2009-03-25T13:08:56.107 回答