c# how do I do a private set property? - c#

I am creating a VECTOR object like so, but I am initializing it in the constructor:
public VECTOR position { get; private set; }
I am doing this operation:
position.x += 2;
VECTOR has a variable x defined as:
public double x { get; set; }
I get the error when I do the +=2 operation that says:
Cannot modify the return value of 'Projectile.position' because it is
not a variable
I want to be able to modify the position vector in the current class, and I want it to be accessible but not modifiable in other classes.

Probably, your problem is with the Vector class actually being a struct. Assume you have the following declarations:
public class Projectile
{
public VECTOR position { get; private set; }
public Projectile()
{
position = new VECTOR();
}
}
public struct VECTOR
{
public double x {get; set;}
}
You cant edit properties of the position property directly because you are accessing a copy of that field (explained here).
If you don`t want to convert your VECTOR into a class you can add a method that updates the position of your projectile:
public void UpdatePosition(double newX)
{
var newPosition = position;
newPosition.x = newX;
position = newPosition;
}
That will create a copy of the position, then update its x property and override the stored position. And the usage would be similar to this:
p.UpdatePosition(p.position.x + 2);

Expose the X property (and others) of VECTOR in a class.
public class myObject {
private VECTOR position;
public double X { get{return position.x;}set{position.x=value;}}
}
Usage example:
myObject.X += 2;

Related

Setting the argument/parameter in C#

I've been working on an assignment for class, beginners C#. I've hit a point where I do not know what to do next. This is the question and it involves argument/parameters...
Define the output of the "area" property calculation such that a user can initialize an instance of the "Circle" class by setting the argument/parameternamed"radius" (in the Constructor) and subsequently call a method named "ShowArea" to display the area of the new circle instance using the formula: (where r = radius, A = area, π= pi)
This is what I have so far:
namespace IndividualAssignment2
{
public class Shape
{
public virtual int area { get; set; }
}
public class Circle : Shape
{
double radius;
public override int area { get; set; }
double ShowArea = 3.14 * Math.Pow(radius,2);
}
public sealed class Square : Shape
{
int height;
}
}
How would I implement this into my code? My double ShowArea is incorrect because radius is underlined. I think understanding this question would help with that issue. Thank you.
If I'm understanding you correctly, ShowArea is a method and not a field. Which means your Circle class should be something like:
public class Circle : Shape
{
double _radius;
// Constructor for the Circle that has radius as a parameter
public Circle(double radius)
{
_radius = radius;
}
// Method that returns the area of the circle using radius value from constructor
public double ShowArea()
{
return Math.Pi * Math.Pow(_radius, 2.0);
}
}
Your class design must be reviewed.
public abstract class Shape
{
public abstract double Area { get; }
}
public class Circle : Shape
{
public Circle(double radius)
{
Radius = radius;
}
private double Radius { get; set; }
public override double Area => 3.14 * Math.Pow(Radius, 2);
}
public class Square : Shape
{
public Square(double edge)
{
Edge = edge;
}
private double Edge { get; set; }
public override double Area => Math.Pow(Edge, 2);
}
Your declaration of the method ShowArea is not correct. You are declaring a field instead.
You should read up more on methods. You were also tasked to declare a constructor with a parameter to set the radius, which I don't find it in your code.

Unity C# Custom class in dictionaries

So yeah, i feel really dumb to ask this question, but i'm currently in the process of writing a simple pathfinder script. I want to use dictionaries like
Dictionary<Floor, FloorInfo>
where floor is the floor tile i am referencing and FloorInfo is custom class as follows:
public class FloorInfo
{
Floor lastFloor;
float floorValue;
public FloorInfo(Floor lastF, float val)
{
lastFloor = lastF;
floorValue = val;
} }
But after i create something like
FloorInfo info = new FloorInfo(current, F);
I cannot get the values, like info.val or info.lastF
Could you explain to me what am I doing wrong? I feel really awkward that i got stuck on something like that or past 45 minutes.
EDIT: Okay, thank you everyone who already answered. Seems like most obvious things can be quite problematic as well. Thanks again and have a nice day!
Make them public if you want to access them from outside the class.
You must mark the fields lastFloot and floorValue as public, or better yet provide a public property for accessing those private fields, like this:
public class FloorInfo
{
private Floor m_lastFloor;
private float m_floorValue;
public Floor LastFloor {
get { return m_lastFloor; }
}
public float FloorValue {
get { return m_floorValue }
}
public FloorInfo(Floor lastF, float val)
{
m_lastFloor = lastF;
m_floorValue = val;
}
}
Then you can access the values like this:
FloorInfo info = new FloorInfo(current, F);
float value = info.FloorValue;
The lastF and val are parameters to your constructor. These are gone as soon as the constructor completes.
You have copied these values to lastFloor and floorValue but currently they are private. You should make these public. If you dont specify a modifier then by default it is private and is not visible outside of the class that they are defined.
public class FloorInfo
{
public Floor lastFloor;
public float floorValue;
public FloorInfo(Floor lastF, float val)
{
lastFloor = lastF;
floorValue = val;
}
}
so you can then reference info.floorValue and info.LastFloor
If you want good design then you should make these into properties and possibly make the set private so they it cannot be changed outside of the FloorInfo class. Also make the properties start with capital letters.
public class FloorInfo
{
public Floor LastFloor { get; private set; }
public float FloorValue { get; private set; }
public FloorInfo(Floor lastF, float val)
{
lastFloor = lastF;
floorValue = val;
}
}
That is because C# class' field's access modifier (by default) is private. What you do above is trying to access private field outside of the scope of the class (which is not allowed).
To access the fields, make its access modifiers public, then you can access them outside of the class scope:
public class FloorInfo
{
public Floor lastFloor; //note the public keyword
public float floorValue;
public FloorInfo(Floor lastF, float val)
{
lastFloor = lastF;
floorValue = val;
}
}
And simply access the fields like:
FloorInfo info = new FloorInfo(current, F);
info.lastFloor = new Floor();
info.floorValue = 45.0;
Note that you do not access the lastF and val from above since they are simply your constructor's parameters. You access the fields of your class, not its constructor's parameters.
That being said, it is more common to access them as property rather than field.
public Floor lastFloor { get; set; }
public float floorValue { get; set; }
This is because with property, you could set something else in your getter and setter (such as checking if the inputs for your property is valid), which is, most of the time, a safer design:
const float floorValueLimit = 20.0;
private float pFloorValue;
public float floorValue {
get { return pFloorValue; }
set {
if (value <= floorValueLimit){ //check limit
pFloorValue = value;
} //else, don't update
}
}
But you cannot do this using field.
Also, as an additional side note, public field would normally have capital letter as its first character in C# typical naming convention:
public class FloorInfo
{
public Floor LastFloor; //note the public keyword
public float FloorValue;
public FloorInfo(Floor lastF, float val)
{
lastFloor = lastF;
floorValue = val;
}
}

How do I use get and set in C#?

I know that this is a pretty obvious question but from what I've seen I can't yet get it.
I don't exactly understand how Getters and Setters work in C#, for instance, I have this code for a character in a game I'm supposed to make for college:
namespace Clase_25_3_2014
{
class Brick
{
private int speed { get; set; }
private Vector2 pos { get; set; }
private Texture2D skin { get; set; }
public Brick(int speed, Vector2 position, Texture2D skin)
{
this.Speed(speed);
this.Pos(position);
this.Skin(skin);
}
}
}
Now, as it stands, where I use the class I try to call it like this:
Brick brick = new Brick(1, Vector2.Zero, mySkin);
brick.GetPos();
Now, obviously that looks weird for you guys, and that's because I haven't yet found out how am I supposed to use it correctly so that it works like a brick.getPos(); from java.
Sorry for the really obvious question, but I can't seem to find an answer for me.
You can't do GetPos because pos is private and you don't have a method called "GetPos". If you make pos public, you can just use Brick.pos to get and Brick.pos(position) to set.
Here's how you could write this class:
namespace Clase_25_3_2014
{
class Brick
{
public Brick(int speed, Vector2 position, Texture2D skin)
{
this.Speed = speed;
this.Pos = position;
this.Skin = skin;
}
public int Speed { get; set; }
public Vector2 Pos { get; set; }
public Texture2D Skin { get; set; }
}
}
Types of Class access:
// lots of explicity (is that a word? :)
public MyClass
{
// Field
// It is recommended to never expose these as public
private int _myField;
// Property (old school, non-auto private field)
public int MyProperty
{
public get
{
return this._myField;
}
public set
{
this._myField = value;
}
}
// Property (new school, auto private field)
// (auto field cannot be accessed in any way)
public int MyProperty2 { public get; private set; }
// Method (these are not needed to get/set values for fields/properties.
public int GetMyMethod()
{
return this._myField;
}
}
var myClass = new MyClass;
// this will not compile,
// access modifier says private
// Set Field value
myClass._myField = 1;
// Get Property Value
var a = myClass.MyProperty;
// Set Property Value
myClass.MyProperty = 2;
// Get Property Value
var b = myClass.MyProperty2;
// this will not compile
// access modifier says private
// Set Property Value
myClass.MyProperty2 = 3;
// Call method that returns value
var c = myClass.GetMyMethod();
When you declare an auto-property in C#, it will get compiled behind the scenes into get and set methods, but you do not need to even think about those. You can access the property as if it were a field.
The benefit of having the property is that you can easily swap it out for a more conventional property with a backing field so that you can provide custom logic in the getter and/or setter. Until you need that, however, it is just extra noise. The auto-property provides the syntactic sugar to avoid that noise.
Brick brick = new Brick(1, Vector2.Zero, mySkin);
Vector2 oldPos = brick.pos;
brick.pos = new Vector2.One;
Try changing to this:
public Brick(int speed, Vector2 position, Texture2D skin)
{
this.Speed = speed;
this.Pos = position;
this.Skin = skin;
}
And with C# you don't need this type of constructors. You can declare an object of this class without constructor with the following way:
public Brick brickTest(){
Speed = 10,
Position = new Vector2(),
Skin = new Texture2D()
};
namespace Clase_25_3_2014
{
class Brick
{
public int Speed { get; set; }
public Vector2 Pos { get; set; }
public Texture2D Skin { get; set; }
public Brick(int speed, Vector2 position, Texture2D skin)
{
this.Speed = speed;
this.Pos = position;
this.Skin = skin;
}
}
}
Using outside:
Brick brick = new Brick(1, Vector2.Zero, mySkin);
Console.WriteLine(Brick.Pos);
however, Behind the scenes the compiler create for each Property:
Private variable storage of the Property-type.
Two function (Get\Set).
Translate the property used to their Functions.
You should just do:
Brick brick = new Brick(1, Vector2.Zero, mySkin);
Vector2 vec = brick.pos;

C# XNA pass by reference classes in constructor

I'm making a vector graphics game in XNA. I've designed a Line class to rotate around a central point to help draw specific shapes. In order to maintain a single point of truth, is there a way to pass a reference to the center of the shape to all of the lines I create, so that updating the center's position will also update the lines' positions? I thought something like this would work:
class Line
{
private Vector2 start;
private double length;
private double angle;
public Line(ref Vector2 start, double length, double angle){
this.start = start;
this.length = length;
this.angle = angle;
}
}
class Obj
{
private Vector2 center;
private Line[] lines;
public Obj(){
center = new Vector2(50,50);
lines = new Lines[5];
for (int i = 0; i < 5; i++){
lines[i] = new Line(ref center,30, (i/5 * 2 * Math.PI));
}
}
}
but the lines do not update when I move the center. What am I doing wrong?
Although the struct is correctly passed by reference to Line, when you assign it internally:
public Line(ref Vector2 start, double length, double angle){
this.start = start;
}
You are actually taking a copy of the struct.
If you ever find yourself needing reference type semantics of struct beyond passing it to a single method then you likely need to reconsider using class.
You can either re-implement the type in a class or wrap the Vector2 in a class and use that:
class Vector2Class
{
public Vector2 Centre;
public Vector2Class(Vector2 inner)
{
Centre = inner;
}
}
class Line
{
private Vector2Class _centre;
public Line(Vector2Class centre)
{
_centre = centre;
}
}
Be aware that you are still working against a copy, but if you share the class you'll all be working on the same copy.
Personally, I would avoid the wrapper and make my own class for representing "centre". This is supported by the largely accepted idea that struct types should be immutable, but you seem to need to mutate the values to keep the representation true.
class CentreVector<T>
{
public <T> X { get; set; }
public <T> Y { get; set; }
}
This only lets you share the data, it doesn't actually notify the lines that the centre has changed. For that you would need some sort of event.
Edited with alternative solution
The problem you're having is because Vector2 is a value type, you're correctly passing it by ref in your methods parameter but then making a local copy of it with the assignment.
I'm not totally sure if you could maintain a pointer to Vector2 in the way that you're thinking but you could create your own Vector2 class that would be a reference type.
class ObjectVector2
{
public float X { get;set; }
public float Y { get; set; }
}
I would like to suggest a slightly different way to achieve the same result by holding a reference to the obj that the lines are a part of.
class Line
{
private Vector2 Center { get { return parent.center; } }
private double length;
private double angle;
Obj parent;
public Line(Obj parent, double length, double angle)
{
this.parent = parent;
this.length = length;
this.angle = angle;
}
}
class Obj
{
public Vector2 center;
private Line[] lines;
public Obj()
{
center = new Vector2(50, 50);
lines = new Lines[5];
for (int i = 0; i < 5; i++)
{
// passing the reference to this Obj in the line constructor.
lines[i] = new Line(this, 30, (i / 5 * 2 * Math.PI));
}
}
}

Accessing property read value inside C# object initializer

I would like to reference a property on an object within an object initializer. The problem is that the variable does not yet exist, so I cannot reference it like normal (object.method). I do not know if there is a keyword to reference the object in creation during the object initialization.
When I compile the following code I get the error - 'The name 'Width' does not exist in the context. I understand why I get this error, but my question is: Is there any syntax to do this?
public class Square
{
public float Width { get; set; }
public float Height { get; set; }
public float Area { get { return Width * Height; } }
public Vector2 Pos { get; set; }
public Square() { }
public Square(int width, int height) { Width = width; Height = height; }
}
Square mySquare = new Square(5,4)
{
Pos = new Vector2(Width, Height) * Area
};
I would like to reference the properties "Width", "Height", and "Area" in terms of "mySquare".
You can't do this as written, but you can define the Pos property to do the same thing. Instead of
public Vector2 Pos { get; set; }
do this
public Vector2 Pos
{
get
{
return new Vector2(Width, Height) * Area;
}
}
Of course, then any square has the same definition for Pos. Not sure if that's what you want.
Edit
Based on your comment I take it you want to be able to specify the value of Pos deferently for different Squares. Here's another idea. You could add a third argument to the constructor which takes a delegate, and then the constructor could use the delegate internally to set the property. Then when you create a new square you just pass in a lambda for the expression you want. Something like this:
public Square(int width, int height, Func<Square, Vector2> pos)
{
Width = width;
Height = height;
Pos = pos(this);
}
then
Square mySquare = new Square(4, 5, sq => new Vector2(sq.Width, sq.Height) * sq.Area);

Categories