I ran into an issue using a struct today that caught me off guard, and I was hoping someone could shed some light on it for me.
I have a struct defined like this:
public struct PaymentDetail
{
public Decimal Amount{get;set;}
public string CheckNumber{get;set;}
public PaymentType PaymentType{get;set;}
}
I have a class that contains this info
public class Transaction
{
public PaymentDetail Payment{get;}
}
I have a presentation model which in which I want to set the underlying properties like this
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");
}
}
}
What's wierd is I can make this work if I change the Payment property to a public field like this:
public class Transaction
{
public PaymentDetail Payment;
}
there's obviosuly something I don't understand about structs that are causing this. Is this a bad idea? Is there a better way? What am I doing wrong?
-
First - don't have mutable structs (i.e. a struct where you can change the values after construction, via setters etc). That is the primary cause of confusion here.
The point is; when you call a property (like
Payment) you get a copy of the value (in your local stack area). For a class, that is a copy of the reference (no problem). For a struct it is a copy of the struct itself. Any changes to that value will be discarded, so the compiler has stopped you from losing data.When it is a public field, you are mutating the original value directly, which is why it doesn't mind. But mutating structs really isn't a good idea.
Make
PaymentDetaila class; that is the correct solution here...In .NET, structs aren't "objects without behaviour" - they are "value-types". Things like "a currency/value pair", "a time range", etc might make valid structs - but not
PaymentDetail.Micah : so everytime I change one of the values it will wipe out the other values in the struct?Marc Gravell : No... it is just that you might not be editing the `PaymentDetail` that you think you are - it will clone itself everytime you blink at it! -
It is probably because you are exposing Payment as readonly, no setter. Since a struct is a value-type, it won't allow you to set a property on the struct if the struct is readonly.
Adding a setter should fix the issue.
I would also consider changing PaymentDetail to a class. I only use structs when it is a very basic value. Something with three properties like this especially if one is a string should be a class.
Jim Mischel : Adding a setter would not fix that problem.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.