Why do the properties in my code not work? - c#

I have created an interface and then derived a class from it:
public interface Ishape
{
void draw();
int Number { get; set; }
}
class Circle : Ishape
{
public Circle(int a)
{
number = a;
}
public void draw()
{
Console.WriteLine("Circle.");
}
private int number;
public int Number
{
get
{
return number;
}
set
{
if (value < -5)
number = -5;
}
}
public int GetNumber()
{
return number;
}
}
class Program
{
static void Main(string[] args)
{
Circle a1 = new Circle(-6);
Console.WriteLine(a1.GetNumber());
Console.ReadLine();
}
}
As you can see, there is an autoproperty in the interface. I then decided to create a property in the new class that derived from the interface that would set the variable "number" to -5 if the value is less than -5. For some reason, the property does not seem to be working. Using the constructor, I set the value of the variable to -6, and the property did not change the value to -5. Why?

This is because you are setting number = a and not Number = a in your constructor. Try this:
public Circle(int a)
{
Number = a;
}

Your Number Property is never actually set.
In your Circle constructor, change number to Number.
public Circle(int a)
{
Number = a;
}
Also, if you intend to use GetNumber as your publicly available get (and nothing more), then I would advise that you change the access modifier for your Number property in your Circle class.

Related

Encapsulating inner class and acessing outside in C#

I have these classes, one is a model, other is Listener and the third one is an Util class. I want to access Terrains by the variable map in the first one, but don't want public access to the inner class Terrain. Is there any way to do it?
It prints error CS0052: Inconsistent accessibility: field type
System.Collections.Generic.List is less
accessible than field `MapaMundiInfoScript.map'
public class MapaMundiInfoScript : MonoBehaviour {
public static bool changeInMap= false;
public static List<Terrain>map = new List<Terrain>();
void Start(){
Terrain terrain = new Terrain(0,0);
Terrain.TerrainPart initialPart = new Terrain.TerrainPart(20,20,0,0);
terrain.terrainParts.Add (initialPart);
map.Add(terrain);
changeInMap=true;
}
class Terrain{
int XPosition;
int ZPosition;
public List <TerrainPart> terrainParts = new List<TerrainPart> ();
public Terrain(int XPosition, int ZPosition){
this.XPosition=XPosition; this.ZPosition=ZPosition;
}
public class TerrainPart
{
int XSize;
int ZSize;
int XPosition;
int ZPosition;
TerrainPartReturn ReturnTerrainPart(int num1,int num2,int num3,int num4)
{
return new TerrainPart (num1,num2,num3,num4);
}
public TerrainPart(int XSize,int ZSize,int XPosition,int ZPosition){
this.XSize = XSize;
this.ZSize = ZSize;
this.XPosition=XPosition;
this.ZPosition =ZPosition;
}
}
}
public class MapListener : MonoBehaviour {
void Update () {
if (MapaMundiInfoScript.changeInMap) {
foreach(MapaMundiInfoScript.Terrain terrain in MapaMundiInfoScript.mapMundi)
{
foreach(terrain.terrainPart terrainPart in terrain.terrainParts)
{
RegionDraw.Draw(terrainPart);
}
}
MapaMundiInfoScript.changeInMap = false;
}
}
public class RegionDraw
{
/***
Implementantion Draw Method
***/
}
You cannot reference a private class as a public property. You will need to have the class public for public access. Consider making your properties and methods private, private protected, internal etc.
If you need to provide read only attributes, you can use public getters and private setters, etc. If you need to prevent the execution of some methods consider setting those to private, etc. The class can be public while still locking down properties and methods inside the class. Consider what it is that you actually need to expose.
You could also expose the functionality of these hidden classes through interfaces
public interface ITerrain
{
List<ITerrainPart> TerrainParts { get; }
ITerrainPart CreateTerrainPart(int XSize, int ZSize, int XPosition, int ZPosition);
}
public interface ITerrainPart
{
// ...
}
Implement them like this
private class Terrain : ITerrain
{
int XPosition;
int ZPosition;
public List<ITerrainPart> TerrainParts { get; } = new List<ITerrainPart>();
public Terrain(int XPosition, int ZPosition)
{
this.XPosition = XPosition; this.ZPosition = ZPosition;
}
public ITerrainPart CreateTerrainPart(int XSize, int ZSize, int XPosition,
int ZPosition)
{
return new TerrainPart(XSize, ZSize, ZPosition, ZPosition);
}
private class TerrainPart : ITerrainPart
{
// ...
}
}
Your listener can then draw like this (after changing the parameter type of Draw to ITerrainPart):
void Update()
{
if (MapaMundiInfoScript.changeInMap) {
foreach (ITerrain terrain in MapaMundiInfoScript.map) {
foreach (ITerrainPart terrainPart in terrain.TerrainParts) {
RegionDraw.Draw(terrainPart);
}
}
MapaMundiInfoScript.changeInMap = false;
}
}
Let MapaMundiInfoScript have a method DrawTerrain() and let Terrain have a method DrawParts. Should you end up with to many incoherent methods in MapaMundiInfoScript, you might want to use a visitor.

Method usage between two classes

here is my code. I want to increase speed value with a.Quest() method. This method is in the first class. And the second class inherits from first class.
Increasing method is in second class but I use it in first class. That's what I'm trying to do. I don't want to write so much code in main.
However when I run the program, both a.Speed and b.Speed is equal to zero. I expect one of them to be 10. How can I fix that?
interface IElektroBeyin
{
int Speed{ get; set; } // Hız kontrolü
}
class AA : IElektroBeyin
{
public int Speed { get; set; }
public virtual void GetFaster() { }
public virtual void GetSlower() { }
public void Quest()
{
int x;
Console.WriteLine("Want to get faster ? 1- Yes");
x = Console.Read();
if (x == 1)
{
GetFaster();
}
}
}
class BB : AA
{
public override void GetFaster()
{
Speed += 10;
}
public override void GetSlower()
{
Speed -= 10;
}
}
static void Main(string[] args)
{
BB b = new BB();
AA a = new AA();
a.Quest();
Console.WriteLine(b.Speed);
Console.WriteLine(a.Speed);
Console.ReadLine();
}
}
}
AA a = new AA();
a.Quest();
AA.Quest() calls AA.GetFaster(), but this method is empty. That's why nothing happens when it is called. BB.GetFaster() is not called since it is in a derived class of AA. You probably want it to be the other way around.
Further, to get a number that a user enters, you can't use the return value of Console.Read(). Use int.Parse(Console.ReadLine()) or something similar.

inherited variable of class2 is different from class1 (C#)

I just made a class Shapes and an other 2 classes ('Triangle' & 'Square') which inherit from 'Shapes'.
public class Shapes
{
private int sides;
}
public class Triangle : Shapes
{
public void init()
{
int sides = 3;
throw new System.NotImplementedException();
}
}
public class Square : Shapes
{
public void init()
{
int sides = 4;
throw new System.NotImplementedException();
}
}
Code is designed using Classdiagram
Question: How should I call the class so that it shows how many sides does a shape has?
Thanks
You need a protected member sides which is used within the init-section of every shape:
public class Shapes
{
protected readonly int sides;
public int NumberOfSides { get { return sides; } }
}
public class Triangle : Shapes
{
public Triangle()
{
this.sides = 3;
}
}
public class Square : Shapes
{
public Square()
{
this.sides = 4;
}
}
As Farhad Jabiyev mentioned using constructors is the usual way to initialize a new instance (see my code above)
Now when you call Shape#NumberOfSides you get 3 for Triangle and 4 for Square:
Shape square = new Square();
int number = square.NumberOfSides();
You need to add a property on the class that has an accessor like this
public class Shapes
{
private int sides;
public int NumberOfSides { get { return sides; } }
}
Then you can go mySquare.NumberOfSides

How can I access members of a private abstract to class for read-only purposes in a public class?

I have a private abstract class called TDSeq in which there are some abstract members and non-abstract members. There are 2 derived classes which it gets data from:- private class TDSeqBuy: TDSeq and private class TDSeqSell: TDSeq.
The members from the private abstract class that I am trying to access are private/public bools/doubles/integers.
The data flows from the derived classes through to the private abstract class by protected abstract name {get;}. After which the data is "moved" to the above mentioned private/public bool/doubles/integers.
I would like to access data for read-only purposes from the abstract class to a public class but do not know how to do that. Could someone please help?
private abstract class TDSeq
{
public event SetupCompletedEventHandler SetupCompleted;
protected abstract double TDSTHigh { get; }
protected abstract double TDSTLow { get; }
protected abstract double SetupStopLevel { get; }
public double highesthigh = 0;
public double lowestlow = 0;
public double truerange = 0;
public double setupstoplevel = 0;
// ...
case TDSTStateSetup.Completed:
if( ValidSetup )
{
Print = "ValidExtSetup";
setupCount++;
SetupDrawText();
//Print = NameIndex;
}
else
{
Print = "ExtSetup Finalised";
tdsetupiscompleted = true;
if (tdsetupiscompleted)
{
Print = "tdsetupiscompleted";
}
if (tdsetupdirection == 1)
{
Print = "tdsellsetupiscompleted";
}
if (tdsetupdirection == -1)
{
Print = "tdbuysetupiscompleted";
}
highesthigh = TDSTHigh;
lowestlow = TDSTLow;
truerange = (highesthigh - lowestlow);
setupstoplevel = SetupStopLevel;
stateSetup = TDSTStateSetup.Finished;
}
// ...
}
I'm trying to publicly access the last 5 lines...
You can also use auto properties to acheive the same without using a private field.
e.g.
private abstract class A
{
protected int Number { get; private set; }
}
private class B : A
{
public int GetNumber()
{
return Number;
}
}
Use protected, not private. Also consider composition over inheritance.
Nested classes are not a good idea. It only limits scope. And protected will not save you there.
If you want access to the properties and them only to be read only, store the values in private fields - and give a protected get property to give read only access to the private fields like so:
private abstract class A
{
private int _number = 5;
protected int Number { get { return _number; } }
}
private class B : A
{
public int GetNumber()
{
return Number;
}
}
private class C : A
{
public int GetNumber()
{
return Number;
}
}
If you want to access data via an object of an abstract class A within a method of a separate, public class X, the abstract class has to be visible to X, so it has to be public (or at least internal, when A and X are part of the same assembly):
public class Program
{
static void Main(string[] args)
{
B b = new B();
X.Test(b);
}
// private does not work here if you want to have a parameter of type A in X
public abstract class A
{
private int _number = 5;
public int Number { get { return _number; } }
}
private class B : A
{
}
}
public class X
{
public static void Test(Program.A a)
{
Console.WriteLine(a.Number);
}
}
Top level classes in an assembly can only be public or internal in terms of accessibility, so I'm assuming your private abstract class and it's derived classes are all nested inside some public class, for starters. Correct?
If so, simply access members of the nested private abstract class that are non-abstract and public by first instantiating the private derived classes inside that parent class via say a public property, then simply call the public field from it:
public class TopClass
{
DerivedClass MyDerivedClass;
public int GetDerivedClassPublicField
{
get
{
DerivedClass MyDerivedClass = new DerivedClass();
return DerivedClass.myfield;//here is access to your abstract class field from outside
}
}
// Private classes must be nested
private abstract class AbstractClass
{
public int myfield = 1;
}
private class DerivedClass : AbstractClass
{
... (derived classes inherit the non-abstract field from the abstract parent by default here) ...
}
}
// now call the public top level class property to get the field in the abstract class
TopClass MyTopClass = new TopClass();
int myInt = MyTopClass.GetDerivedClassPublicField;

A field is fixed value for each class,field is not dependent instances ...?

In below example, i defined number field. This field will work as i wanted but it is not enough efficient to provide my expectations.
number value is fixed value for each class,number is not dependent instances and number support polymorphism. How can i do that ? Or is there another solution for not use unneccesary number field for instances ?
abstract class Main
{
public int number;
public virtual void dostuff(){
int x = number;
}
}
class Derived:Main
{
public ovverride void dostuff(){
int x = number;
}
}
You could just make the number a property and initialise is in each class constructor:
abstract class Main
{
public int number{get; private set;}
public void dostuff(){
int x = number;
}
}
class Derived:Main
{
public Derived()
{
number = 5; // Specific value for each derived class
}
public void dostuff(){
int x = number;
}
}
Looks like I got the wrong end of the stick -- you want to be able to set it statically per class type, which has already been answered.
You could make the property static and then add it to each class:
abstract class Main
{
public static int number;
public virtual void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public overide void dostuff(){
int x = Derived.number;
}
}
Edit: I am a bit confused by your comments about polymorhism so i have added some more examples.
Main obj = new Derived();
obj.doStuff(); //This will use Derived.number; as doStuff is and overidden virtual method.
However if you do the following:
abstract class Main
{
public static int number;
public void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public new void dostuff(){
int x = Derived.number;
}
}
Then you get different behaviour as below:
Main obj = new Derived();
obj.doStuff() // Will use Main.number
Derived obj2 = (Derived)obj;
obj2.doStuff() // Will use Derived.number
If you want some other kind of behaviour i havn't defined here please exaplin because i do not understand what you want.

Categories