Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to work with value types in c# using properties?

I have a small class called Tank has one public member called Location which is a Rectangle(a struct). When I write:

Tank t = new Tank();
t.Location.X+=10;

everything works fine, and the tank moves.

But after I changed the member to be a property, I can no longer use this syntax. It doesn't compile, because the t.Location is now a property(which is function) and returns a temporary copy of the location(because it's a value type).

The only way I can use Location now is to do something like this :

k = t.Location 
k.X +=10;
t.Location = k;

Is there any workaround that can help me not to write this ugly code, and use the intuitive a+=10; syntax?

like image 967
OopsUser Avatar asked Feb 25 '13 19:02

OopsUser


People also ask

What are the 5 data types in C?

Types of Data Types in CFloating-point, integer, double, character. Union, structure, array, etc.

How do you determine the data type of a value?

The typeof operator in JavaScript allows you to determine the type of value or type of value that a variable contains . There is just one operand for the typeof operator (a unary operator), which takes one variable as input. It determines the operand's type and a string is returned as a result.

What is data type explain data types in C?

In the C programming language, data types constitute the semantics and characteristics of storage of data elements. They are expressed in the language syntax in form of declarations for memory locations or variables. Data types also determine the types of operations or methods of processing of data elements.


2 Answers

From @ Servy
"structs are immutable" well, no, they're not. They should be, in most cases, but they are not inherently immutable. The inherent problem here is that the property returns a copy of the struct, not a reference to the struct. If there was a syntax in C# for ref returns, then this would be possible.

Fundamentally why this will not work is that structs are immutable. Once they're made, that's it. For this reason it is not possible to partially reassign a struct. It would be like trying to swap your leg out. You can't. It's part of you, and you came with it!

I think the only thing you're going to be able to do is implement your own X and Y attributes, such that:

public double LocationX
{
   get
   {
       return Location.X;
   }
   set
   {
       Location = new Rectangle(value,Location.Y);
   }
}

You obviously need to mirror this to Y as well, but this should allow what you want (but don't expect it to be quick or efficient!)

Whilst this answers your immediate question, I would raise a few points about your model. I would consider not attempting to update the movement like this. From an OO point of view, your tank is its own object, and should be managing its own position. Give it a movement instruction, and then have it update it's own position.

e.g:

Tank.MoveRelative(10,0);   
Tank.MoveAbsolute(100,100);

this allows you a little more freedom and allows the tank to validate any requests made on it based on logic you've given it.

like image 97
Immortal Blue Avatar answered Sep 29 '22 11:09

Immortal Blue


This problem occurs pretty often when you start programming in 2D and 3D space using properties. Generally, the best workaround is to implement addition between two vector structures or two differing structures that would add together in a logical manner (in your case, you would implement addition between a 2D vector and your rectangle to offset its position - you wouldn't add two rectangles together).

Doing so, allows you to write:

myTank.Location += new Vector2(10, 0);

Which, while still slightly clunky, allows you to make changes for both components in a single operation. Ideally, the added vector would be a velocity vector which you would use to update your tank's location.

like image 37
Jason Lim Avatar answered Sep 29 '22 11:09

Jason Lim