Reputation: 422
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
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
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