AllDayPiano
AllDayPiano

Reputation: 422

C# Cannot change return value?

I'm a little hung on C# structs. I have the following code extract (sorry for the mass - i reduced as much as possible):

namespace Generics
{
    public struct Generic
    {
        public struct Traverse
        {
            public double TraverseWidth, CurrentPosition;
        }
    }

    public class XXXSettings
    {
        private Generics.Generic.Traverse _TRAVERSE;

        public Generics.Generic.Traverse TraverseData
        {
            get { return _TRAVERSE; }
            set { this._TRAVERSE = TraverseData; }
        }

        public XXXSettings()
        {
            _TRAVERSE = new Generics.Generic.Traverse() { CurrentPosition = 0, TraverseWidth = 0 };
        }
    }
}

namespace XXX_Driver
{
    public class XXXClient
    {
        private Generics.XXXSettings _Settings;

        public Generics.XXXSettings Settings
        {
            get { return _Settings; }
            set { this._Settings = Settings; }
        }
        public bool Connect()
        {
            if (this.Settings == null)
            {
                throw new ArgumentNullException();
            }

            Settings.TraverseData.TraverseWidth = "1234";

        }
    }
}

My problem: The last line of code

Settings.TraverseData

is marked as "The return value of XXXSettings.TraverseData can not be changed because it is no variable."

But why is this? I'm used to structs from VB.NET and don't know this behavior?!

Even

_Settings.TraverseData.TraverseWidth = new Generics.Generic.Traverse() { TraverseWidth = 1234, CurrentPosition = 0 };

won't help. Is there at least ANY use for structs in C#? I thought it's a conglomerate of values but if they're not accessible?!

Thanks for some explaination and some hints, how I should change my code :)

Upvotes: 1

Views: 127

Answers (2)

Rob
Rob

Reputation: 27367

structs do not behave the way you'd expect. They are immutable.

var myStruct = new Struct { Name = "Rob", Gender = "m" };
myStruct.Name = "Test"; 

This code creates a struct with the Name "Rob". Then, it creates a new struct, copies the values over, except for Name, which it sets to Test.

Now, the reason you're having this error is because you're using a property, not a field or variable. .NET only performs this 'copy-and-replace' automatically for variables.

There are two ways to fix your code... use a field (not the best approach):

public Generic.Traverse TraverseData;

Or, use class instead of struct - This approach is probably better suited to you.

Use structs sparingly. It's almost never a good idea to change a property of a struct, they're meant to be immutable. And, while you're learning C#, it's very unlikely you'll need to use a struct instead of a class.

VB has the same behavior, as shown here:

Sub Main
    Dim a as A
    a = new A()
    a.Prop2.Name = "A"
End Sub

Structure Test
    public Name as String
End Structure

Class A
    public property Prop2 As Test = new Test()
End Class

Gives the error

Expression is a value and therefore cannot be the target of an assignment.

Changing it to public Prop2 As Test = new Test() (or using a class instead of struct) works as expected.

Upvotes: 2

Perfect28
Perfect28

Reputation: 11317

Actually, TraverseData is not a variable :

public Generics.Generic.Traverse TraverseData
{
    get { return _TRAVERSE; }
    set { this._TRAVERSE = TraverseData; } // Mistake is here !!
}

Use value keyword to retrieve the actual set value :

public Generics.Generic.Traverse TraverseData
{
    get { return _TRAVERSE; }
    set { this._TRAVERSE = value; } 
}

Upvotes: 3

Related Questions