tags:

views:

167

answers:

3

in a file I defined a public struct

public struct mystruct
{
    public Double struct1;
    public Decimal struct2;
}

In another I tried to do this:

class Test
{
    mystruct my_va;

    public mystruct my_va
    {
        get { return my_va; }
        set { my_va = value; }
    }

    public Test()
    {
        my_va.struct1 = 10;
    }
}

Intellisense recognizes My_va.struct1 but compiler says

Error 1 Cannot modify the return value of 'TEST.mystruct' because it is not a variable

How to correct the syntax ?

+20  A: 

Yup, it's absolutely right. You see, when you fetch My_va, you're fetching a value - a copy of the current value of my_va. Changing that value would have no benefit, because you'd be immediately discarding the copy. The compiler is stopping you from writing code which doesn't do what it looks like it does.

In general, avoid mutable structs. They're evil. In this case, you could (for example) change mystruct to be immutable, but with a method like this:

public mystruct WithStruct1(double newValue)
{
    return new mystruct(newValue, struct2);
}

then change your constructor code to:

My_va = My_va.WithStruct1(10);

... although in this case it's far more likely (given that you're in a constructor) that you should be writing:

My_va = new mystruct(10, 0);

Not only should structs be immutable, they should be pretty rare in most codebases, IMO. Other than for Noda Time, I've hardly ever written my own custom values types.

Finally, please learn the .NET naming conventions and try to follow them, even for sample code :)

Jon Skeet
I once heard tale of a mutable struct burning an entire village. Twas madness.
Anthony Pegram
@Anthony: You "once heard a tale"? You make it sound like you don't believe it. I was there, and saw it all. It still haunts me at night.
Jon Skeet
Anakin Skywalker was cool until he learned about mutable structs.
Josh Einstein
I once defeated a mutable struct using nothing but a rake and a large glass of water.
Joel Etherton
Who wins the fight, mutable struct or grue?
Marc
@Marc - that depends. Does grue have a rake and a large glass of water?
Joel Etherton
@Joel: You have to explain how! I was mugged by a mutable struct yesterday night and it stole all my references.
Callum Rogers
@Callum Rogers - I don't really know how, but I believe it involved water boarding it while pinning it to the ground with the rake. I sorta blacked out when I saw it.
Joel Etherton
Sorry I'm c# beginner, I don't understand your code. Why mystring ? isn't it mystruct ?
@user, yes, it should be mystruct. Typo.
Anthony Pegram
@Anthony Pegram - and none of us is so brazen as to dare edit a post submitted by the Mighty Skeet.
Joel Etherton
+5  A: 

It is highly recommended to avoid mutable structs. They exhibit all sorts of surprising behaviour.

Solution: Make your struct immutable.

public struct MyStruct
{
    public readonly double Value1;
    public readonly decimal Value2;

    public MyStruct(double value1, decimal value2)
    {
        this.Value1 = value1;
        this.Value2 = value2;
    }
}

Usage:

class Test
{
    private MyStruct myStruct;

    public Test()
    {
        myStruct = new MyStruct(10, 42);
    }

    public MyStruct MyStruct
    {
        get { return myStruct; }
        set { myStruct = value; }
    }
}
dtb
@Caspar Kleijne: Value1 and Value2 are fields, not auto-properties. So, no.
dtb
right, sorry.... public fields are ugly....
Caspar Kleijne
Thanks that works but can you explain WHY your syntax works and not mine, I can't really understand the fundamental difference: why by making it readonly has anything to do with setting the property value ?
@user310291: As *@Jon Skeet* explained, structs have value semantics and you were actually modifying a field of a copy, not the struct value you intended to modify. This is a common source of errors, so even the C# compiler warns you about this. If you make a struct immutable (= all fields readonly), you can never accidentally modify a copy. (BTW the `set` accessor has nothing to do with this; your original code never used it.)
dtb
Well if it was only a warning it would be ok, but it just can't let me do it :)
something I don't understand now: readonly doesn't it mean you cannot CHANGE its value ?
@user310291: `public readonly double Value1;` means that you cannot change `Value1`. But `private MyStruct myStruct;` means that you can change `myStruct` (*not* the contents of `myStruct`!).
dtb
+1  A: 

use static structure instead for this purpose.

public static  struct mystruct
    {
        public static  Double struct1;
        public static Decimal struct2;
    }

you won't have to use an object & can access like :

TEST.mystruct.struct1 = 10;

as it seems the namespace is TEST from the error.

EDIT : Wrong Invalid method. Please ignore. Though letting me know why VS IDE allows would be good

loxxy
`static struct`? What's that?
dtb
anything wrong with that??
loxxy
@dtb: It's a source of compilation errors :)
Jon Skeet
@loxxy: Did you try to compile it? What do you think it would achieve, even if it were valid?
Jon Skeet
loxxy
I downvoted this but someone agrees, can you please explain?
Caspar Kleijne
@loxxy: You should get "Test.cs(4,22): error CS0106: The modifier 'static' is not valid for this item"
Jon Skeet
wat in the world....why dunt I get that warning then?
loxxy
@loxxy: Wrong language? Try a C# compiler.
dtb
Strange...when I compiled it did give me an error at the console. But why doesnt it give an error in the IDE (VS 2008)?
loxxy
It says the modifier static is not valid for this item ?
yea..it does. Structures cannot have static modifiers...I recently realized.
loxxy