C# how to use the Parent class property in child class - c#

I have following class which has Parent class Shapes which has property Radius and i am accessing this property into its child class(HeaxGon) but it gives me error in child class ( get or set accessor expected)
Please advise.
class Shapes
{
int _radius;
public int Radius
{
get { return _radius; }
set { _radius = value; }
}
}
class HeaxGon:Shapes
{
int points;
public void SetRadius
{
**Radius=20;**
}
}

I am guessing you are trying to create a function called SetRadius, in which case, this is what it should look like:
public void SetRadius(int radius)
{
this.Radius = radius;
}
Or if you really want to set it to 20 in all cases:
public void SetRadius()
{
this.Radius = 20;
}

You wrote it badly, it should look like this:
class Shapes
{
int _radius;
public int Radius
{
get { return _radius; }
set { _radius = value; }
}
}
class HeaxGon:Shapes
{
int points;
public void SetRadius()
{
Radius=20;
}
}
There's no need calling "this" like others have suggested.
Or simply work with the property you've already exposed in your base class
HeaxGon hg = new HeaxGon();
hg.Radius = 20;
This will call your setter you've specified in your base class (Shapes).

Make _radius protected, and then simply call this.Radius in the child class. So:
public class Shape
{
protected int _radius;
public int Radius
{
get { return _radius; }
set { _radius = value; }
}
}
public class Hexagon : Shape
{
int _points;
public void SetRadius(int radius)
{
this.Radius = radius;
}
}

Related

call this() constructor and different base() constructor

I have some classes that all extend a parent class. like so:
public abstract class EasyUIELementFoundation
{
protected GameObject UIElement;
private RectTransform RectOptions;
private Vector2 _position;
private Vector2 _dimensions;
protected Vector2 Position
{
get
{
return _position;
}
set
{
RectOptions.pivot = value;
_position = value;
}
}
protected Vector2 Dimensions
{
get
{
return _dimensions;
}
set
{
RectOptions.sizeDelta = value;
_dimensions = value;
}
}
protected EasyUIELementFoundation()
{
UIElement = new GameObject();
RectOptions = UIElement.AddComponent(typeof(RectTransform)) as RectTransform;
}
protected EasyUIELementFoundation(Vector2 position) : this()
{
_position = position;
}
protected EasyUIELementFoundation(Vector2 position, Vector2 dimensions) : this()
{
_dimensions = dimensions;
_position = position;
}
}
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent;
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : base()
{
UIImageComponent = UIElement.AddComponent(typeof(RawImage)) as RawImage;
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : this() : base(position)
// here is the error it is not possible to call the base.
{
//some code...
}
}
So my problem is i have 3 different base class constuctors and from the derived class i want to call different base constructors, but i cant atm. Is this even possible if not how would i go about doing such a thing?
If anything is unclear let me know so i can clarify.
I am a complete newb to OOP so sorry if this is a bit of a weird question.
Invoking this() will invoke a base constructor, implicitly or explicitly. Therefore, the other invocation of base would be the second time you construct the same object, which is not allowed.
You can share the code of the constructor by creating a private helper method, like this:
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent;
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : base()
{
InitUiImageComponent();
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : base(position)
{
InitUiImageComponent();
//some code...
}
private void InitUiImageComponent() {
UIImageComponent = UIElement.AddComponent(typeof(RawImage)) as RawImage;
}
}
In your specific case initialization code could be placed directly into the initializer, so the helper method becomes unnecessary:
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent = UIElement.AddComponent(typeof(RawImage));
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : base()
{
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : base(position)
{
//some code...
}
}
You cannot call a this and a base constructor at the same time. Usually the best approach is as already mentioned in the comment to first implement the constructor that is the most complex (has most parameters) and call the base class. Then make the simpler constructor call the complex ones with default values.
With this approach your class will then end up looking like this:
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent;
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : this(default(UnityEngine.Object), default(Vector2))
{
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : base(position)
{
UIImageComponent = UIElement.AddComponent(typeof(RawImage)) as RawImage;
//some code...
}
}

How can I force a child to call a parent method?

I have a base class with a method. I want to force all children of this class to call this base method somewhere in their code.
public class BaseClass
{
public void BaseMethod()
{
//Do something
}
}
public class ChildClass1 : BaseClass
{
public void ChildMethod()
{
BaseMethod();
}
}
public class ChildClass2 : BaseClass
{
public void ChildMethod()
{
//Doesn't call BaseMethod();
}
}
So I want ChildClass1 to be fine, but I want ChildClass2 to throw an error.
The reason I want to do this is because my base class has a value that I don't want to forget to implement in my child class. For example, if I am making a bunch of enemies for a game, and the Enemy class has a speed modifier, I don't want to forget to include that in all of the children methods:
public class Enemy
{
public float x;
public float y;
private float speed;
public float GetSpeed()
{
return speed;
}
public void SetSpeed(float speed)
{
this.speed = speed;
}
}
public class Goomba : Enemy
{
public void Move()
{
x += 5 * GetSpeed();
}
}
public class Turtle: Enemy
{
public void Jump()
{
y += 5; //This is wrong. I forgot to adjust for speed.
//y += 5 * GetSpeed(); This is what I want to force myself to do
}
}
Although it is not actually for movement. This is an oversimplification. The base class contains ability modifiers, where the children class are unique abilities that use the modifiers.
How can I structure my code such that a child is required to call a specific parent method somewhere in the code?
You can use the TemplateMethod design pattern
public class BaseClass
{
public void BaseMethod()
{
DoSomething();
TemplateMethod();
}
protected abstract void TemplateMethod();
}
So you make your derived classes implement the template method, but clients of that class call the BaseMethod method. This forces the DoSomething() bit to execute but allows the derived classes to include their own logic.
So a simple example in the case of enemy (obvs adapt so it meets your needs).
public abstract class Enemy
{
public float x;
public float y;
private float speed;
public float GetSpeed()
{
return speed;
}
public void SetSpeed(float speed)
{
this.speed = speed;
}
public void Move()
{
x += GetMovementAmount() * GetSpeed();
}
public abstract decimal GetMovementAmount();
}
public class Goomba : Enemy
{
public void GetMovementAmount()
{
return 5;
}
}
public class Turtle: Enemy
{
public void GetMovementAmount()
{
return 6;
}
}
You could rearrange the code so that changing the position is possible only in base class:
public class Enemy
{
public float x { get; private set; }
public float y { get; private set; }
private float speed;
public Move(float dx, float dy)
{
x += dx * speed;
y += dy * speed;
}
}
Create a new class ability. It will allow you to control what happens when it is run and the user gets to make the run do whatever they want.
public class Ability
{
Action myAct { get; set; }
public Ability(Action inAct)
{
myAct = inAct;
}
public Run()
{
DoStuffBefore();
myAct();
DoStuffAfter();
}
}

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;
}
}

Weird Behaviour when initiate a class

I'm working on a game, and I made all the building blocks. now I'm working on the game logic and rendering.
I have abstract Monster class and a class call GreenMonster that inherits from it.
Now the weird thing is, when I try to init a GreenMonster object.
when I do this:
private void initGreenMonsters()
{
for (int i = 0; i < greenMonsters.Length; i++)
{
greenMonsters[i] = new GreenMonster(new Point(0,40),new Size(40, 40));
}
}
every thing works like I planned and I can render the images on the form.
but when I try to init like that:
private void initGreenMonsters()
{
for (int i = 0; i < greenMonsters.Length; i++)
{
greenMonsters[i] = new GreenMonster();
greenMonsters[i].Position = new Point(0, 40);
greenMonsters[i].Size = new Size(40, 40);
}
}
I don't get any errors, and the app runs, but I can render the monsters.
This is the Monster class constructor and the Draw Method I use to draw a Monster:
public Monster(Point _startPosition,Size _size)
{
this.size = _size;
this.position = _startPosition;
}
public virtual void Draw(Graphics g)
{
Rectangle monsterRec = new Rectangle(position, size);
g.DrawImage(img, monsterRec);
}
and this is the GreenMonster class constructor:
public GreenMonster(Point _startPosition, Size _size)
: base(_startPosition, _size)
{
this.img = new Bitmap(SpaceInvadersGame.Properties.Resources.NormalMonster);
this.hp = 1;
this.speed = 1;
}
public GreenMonster()
{
this.img = new Bitmap(SpaceInvadersGame.Properties.Resources.NormalMonster);
this.hp = 1;
this.speed = 1;
}
the only thing that bothers me is, that when I'm looking at both ways I init the objects, it just looks the same..
I just can't find any different between in both of the ways.
someone have any idea how its different?
If you need more code so the question is more clear, I would be happy to add!
this is the Monster class and its properties
public abstract class Monster
{
protected Point position;
public Point Position { get { return position; } set { position = value; } }
protected Size size;
public Size Size { get { return size; } set { value = size; } }
public int speed;
protected Bitmap img;
protected int hp;
public int HP { get { return hp; } }
public void SetStartingPosition(int x, int y)
{
this.position = new Point(x, y);
}
public virtual void Draw(Graphics g)
{
Rectangle monsterRec = new Rectangle(position, size);
g.DrawImage(img, monsterRec);
}
}
You are setting your incoming value to the current size, rather than setting the current size to the incoming value, in the method below:
public Size Size { get { return size; } set { value = size; } }
should be
public Size Size { get { return size; } set { size = value; } }
Your code for Position looks OK though:
public Point Position { get { return position; } set { position = value; } }

Get/Set The Members of a Struct or a Class in a Class C#

If I have a Struct or a Class, lets say I'm using a Vector2 (which has two members, float X and float Y), how am I supposed to properly get/set its methods in a class?
This is the code I know of right now:
public class MyClass
{
private Vector2 vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
}
But what if I wanted to edit the members (or certain members) of the Vector2 with the set method? Something like this is what I'm asking for:
set.X
{
vector.X = value.X;
}
set.Y
{
vector.Y = value.Y;
}
And it would be called as simply as Vector.X = 5. I thought up an alternative, using something like public float VectorX { set { vector.X = value; } } but I would prefer a more logical and object-orientated way. Is there?
It makes a BIG difference whether Vector2 is a class or a struct.
Since Vector2 is a class you can simply do
obj.Vector.X = 5;
having
public class MyClass
{
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
}
If, however Vector2 was a struct then you cannot modify the return value from the get. If you try you will get a compile error:
Cannot modify the return value of ... because it is not a variable.
You can work around this using the method you suggested with
public float VectorX
{
get { return _vector.X; }
set { _vector.X = value; }
}
public float VectorY
{
get { return _vector.Y; }
set { _vector.Y = value; }
}
or you could provide a wrapper class around Vector2 like:
class Vector2Wrapper
{
public Vector2 Vector;
}
and then store a Vector2Wrapper in MyClass like
public class MyClass
{
private Vector2Wrapper _vector2Wrapper;
public Vector2Wrapper VectorWrapper
{
get { return _vector2Wrapper; }
set { _vector2Wrapper= value; }
}
}
and you can then modify it like
obj.VectorWrapper.Vector.X = 5;
you can't specify a submethod to handle that partial set, because that set is handled by the Vector class and us thus out of your scope. the moment someone calls Myobject.Vector they are calling your get funcion, but when it moves on to .X they are calling the Vector.get_X function.
This may be easier to see by looking at the compiled code using the ILDasm tool, which reveals the actual method calls your properties make sugar out of.
Now, what you CAN do is to wrap certain properties, as mentioned. The result would like like so.
public class MyClass
{
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
public float VectorX
{
get { return _vector.X; }
set { _vector.X = value; }
}
public float VectorY
{
get { return _vector.Y; }
set { _vector.Y = value; }
}
}
Another option might be to use the pattern of INotifyPropertyChanged in your Vector class, raising an event every change which your MyClass can then listen to and react to, thus applying logic when child elements are updated.
There is also the option of using an indexer property
public class MyClass
{
public enum Axis { X, Y }
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
public float this[Axis axis]
{
get { return axis == Axis.X ? vector.x : vector.y; }
set
{
if(axis == Axis.Y)
{
// Special logic here
vector.Y = value;
}
if(axis == Axis.X)
{
// Special logic here
vector.X = value;
}
}
}
}
Because Vector2 is a struct, you are getting a COPY. You need to use the setter to set a new Vector2. There are 2 ways:
Vector2 v = myClass.Vector; //get a copy of the vector
v.X = 5f; // change its value
myClass.Vector = v; // put it back
I don't really like the following, but it's one statement:
myClass.Vector = new Vector2(2f, myClass.Vector.Y)
Inside MyClass, you can create a property that sets only the X value:
public float X {
get { return Vector.X; }
set {
Vector2 v = Vector;
v.X = value;
Vector = v;
}
}
(Vector can be an automatic property)

Categories