I do not understand why I get CS0120 - c#

I am having one error and have searched for answers in my book and watched tutorials for this particular subject. The large gap is to indicate another class I added called Point
class Program
{
private static Point another;
static void Main(string[] args)
{
Point origin = new Point(1366, 768);
Point bottomRight = another;
double distance = origin.DistanceTo(bottomRight);
Console.WriteLine("Distance is: {0}", distance);
Console.WriteLine("Number of Point objects: {0}", Point.ObjectCount());
}
}
class Point {
private int x, y;
private int objectCount = 0;
public Point()
{
this.x = -1;
this.y = -1;
objectCount++;
}
public Point(int x, int y)
{
this.x = x;
this.y = y;
objectCount++;
}
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
int yDiff = this.y - other.y;
double distance = Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff));
return distance;
}
public static int ObjectCount()
{
**return objectCount;**
}
}

Your ObjectCount() method is static method while your property is not.
public static int ObjectCount()
As you are reading from a property which is not allocated in your code. So, remove the static keyword from the methods signature.
public int ObjectCount()
{
return objectCount;
}

1) please post full code in separate blocks, also please tell people where exactly you get the error;
2) my guess is that error CS0120 comes from the line: Console.WriteLine("Number of Point objects: {0}", Point.ObjectCount());
Yet again, I guess that you wanted to count all of the Point objects created. Your mistake is making objectCount an instance member.
You see, every instance of Point class will have its own objectCount, and it will always be 1 after constructor finishes. For the very same reason you can not call Point.ObjectCount() and return objectCount from it, because objectCount is not a static member, it's bound to an instance.
To fix your code, make objectCount static. That way there would be only one objectCount for all instances of Point.

Related

struct in C# doesn't work as expected

I'm working on a simple application and I'm a little confused. I have a simple struct Point with int x and int y. And I use it for Line
public class Line : Shape {
public Line() {
PointA = new Point(x: 0, y: 0);
PointB = new Point(x: 0, y: 0);
}
public Point PointA { get; set; }
public Point PointB { get; set; }
}
and somewhere
var line = new Line();
line.PointB = new Point(x: 4, y: 2);
Console.WriteLine($"Line start at {line.PointA.GetX()}:{line.PointA.GetY()}; end at {line.PointB.GetX()}:{line.PointB.GetY()}");
for (int i = 0; i < 10; i++) {
line.PointB.IncrementX();
line.PointB.IncrementY();
}
Console.WriteLine($"Line start at {line.PointA.GetX()}:{line.PointA.GetY()}; end at {line.PointB.GetX()}:{line.PointB.GetY()}");
Here need to increment x and y of Point but result doesn't change:
Line start at 0:0; end at 4:2
Line start at 0:0; end at 4:2
What I'm doing wrong? It seems strange. Are there some specific rules to use struct in C#. I know that this is a value type but I think it is a good for Point. All examples uses struct for Point. Please help?
Point:
public struct Point {
private int _x;
private int _y;
public Point(int x, int y)
: this() {
_x = x;
_y = y;
}
public void IncrementX() {
_x++;
}
public void IncrementY() {
_y++;
}
public int GetX() {
return _x;
}
public int GetY() {
return _y;
}
}
Struct is a value type. And it is passed by value (i.e. by creating copy of all fields) instead of passing reference to struct instance. So when you do
line.PointB.IncrementX()
When you call getter of PropertyB, it returns copy of Point which is stored at PropertyB backing field. And then you call increment on copy. Thus original value will stay unchanged.
Further reading: Value and Reference Types and especially Mutating Readonly Structs which says
mutable value types are evil. Try to always make value types
immutable.
What you can do if you want to actually move line point?
Change Point type to class. Then it will be passed by reference, and all methods will be called on original point which you store in Line.
Assign new (modified) point instance to line
I.e. you should store copy, change it and assign back
var point = line.PointB; // get copy
point.IncrementX(); // mutate copy
point.IncrementY();
line.PointB = point; // assign copy of copy
You can also make your Point struct immutable (the best thing you can do for value types):
public struct Point
{
public Point(int x, int y)
{
X = x;
Y = y;
}
public int X { get; }
public int Y { get; }
public Point IncrementX() => new Point(X + 1, Y);
public Point IncrementY() => new Point(X, Y + 1);
public Point Move(int dx, int dy) => new Point(X + dx, Y + dy);
}
And now changing location will look like
line.PointB = line.PointB.Move(1, 1);

2D-array as a class property - how to create them the C# way?

I am trying to create a class with a property that is a two-dimensional array. The array will hold various x,y coordinates on a grid (e.g. 0,1 or 3,7) and the size of the array is dependent on a class property called size.
How would you go about creating this array in C#? I have given my solution below, but having very little C# experience and coming from a Python background with some javascript knowledge, it feels like that there is a better solution to this problem.
Could one of you C# wizards enlighten me, please?
Thanks in advance for your help.
Here is my code:
public class Obj
{
int Size; // Defines length of array
int[,] Pos;
// constructor
public Obj(int size)
{
this.Size = size;
this.Pos = new int[size, 2];
}
public void set_coord(int index, int x, int y)
{
if (index >= this.Size) {
Console.WriteLine("Catch OutOfRangeException");
}
else
{
this.Pos[index, 0] = x;
this.Pos[index, 1] = y;
}
}
You could create a List instead of a class, and have an internal sub class to represent your points.
Like this
public class Obj{
int Size;
List<Point> Pos = new List<Point>();
public Obj(int size){
this.Size = size;
}
public set_coord(int index, int x, int y){
if(index >= this.Size){
Console.Writeline("Catch OutOfRangeException")
}else{
this.Pos.Add(new Point(x,y));
}
}
}
class Point{
int x = 0;
int y = 0;
public Point(int xCor, int yCor){
this.x = xCor;
this.y = yCor;
}
}
A struct is the ideal approach for this. A full blown class may not be necessary, but it depends.
https://msdn.microsoft.com/en-us/library/ah19swz4.aspx
public struct Coordinates
{
public int coordX;
public int coordY;
}
The property then in your class could be set like this:
var Obj = new Obj();
List<Coordinates> listOfCoords = new List<Coordinates>();
var coord = new Coordinates();
coord.X = 20;
coord.Y = 15
listOfCoords.Add(coord);
Obj.Pos = listOfCoords
Keep in mind that Structs cannot be inherited from, or inherit, other classes or structs, as well as a few other gotchas. If you need these features, or the data in your struct is prone to modification after it is created (in other words, the data is NOT immutable), consider a small class instead.
https://msdn.microsoft.com/en-us/library/0taef578.aspx

How to tie one variable to another

I have this bit of code:
Brick brick1= new Brick(parent.X - 1,parent.Y);
X & Y are integers,
Basiclly what i want to do is: when the x of the parent brick changes, the x of brick1 changes,where it dosnt matter the value of parent.X, brick1.X will always be equal to parent.X - 1
Is there an way of accomplishing this?
Assuming that Brick is not a struct you could do this. You could also do this through inheritance with a ChildBrick class but unless you need the added complication, at least in my mind, it is simpler to just allow Brick to have a parent that is a Brick and add a constructor for the parent. Then if you retrieve a value and it needs to be computed from the parent you just check for whether you have a parent and calculate accordingly.
class Brick
{
private Brick _parent;
private int _x;
private int _y;
Brick(Brick parent) {_parent = parent);}
Brick(int x, int y)
{
_x = x;
_y=y;
}
public int X
{
get
{
if (_parent != null) return _parent.X - 1;
return _x;
}
}
public int Y
{
get
{
if (_parent != null) return _parent.Y;
return _y;
}
}
}
Just make brick1 a derived class with a calculated read only property
public class childBrick: Brick
{
public new float X
{
get { return base.X - 1.0 }
private set { base.X = value; }
}
public static Brick Make( float x, float y)
{
return new childBrick
{
X = x;
Y = y;
}
}
}
use it like this
Brick brick1 = childBrick.Make(parent.X - 1,parent.Y);

Why can't I call this constructor with two arguments in C#?

I'm new to C# and I'm learning about scope. Just making a simple program to calculate the length of a line based on the coordinates of the two endpoints in the line. In line 7 of the code below I am getting a compiler error saying that the constructor of the Line class cannot take two arguments. Why is that? And then at around line 30 and 31 I cannot get the GetLength method to recognize the bottomRight point and the origin point. Any advice would be appreciated, thanks!
class Program
{
static void doWork()
{
Point origin = new Point(0,0);
Point bottomRight = new Point(1366, 768);
Line myLine = new Line(bottomRight, origin);
//double distance = origin.DistanceTo(bottomRight);
double distance = GetLength(myLine);
Console.WriteLine("Distance is: {0}", distance);
Console.WriteLine("Number of Point objects: {0}", Point.ObjectCount());
Console.ReadLine();
}
static void Main(string[] args)
{
try
{
doWork();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static double GetLength(Line line)
{
Point pointA = line.bottomRight;
Point pointB = line.origin;
return pointA.DistanceTo(pointB);
}
}
class Line
{
static void Line(Point pointA, Point pointB)
{
pointA = new Point();
pointB = new Point();
}
}
And here is the code for the Point class:
class Point
{
private int x, y;
private static int objectCount = 0;
public Point()
{
this.x = -1;
this.y = -1;
objectCount++;
}
public Point(int x, int y)
{
this.x = x;
this.y = y;
objectCount++;
}
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
int yDiff = this.y - other.y;
double distance = Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff));
return distance;
}
public static int ObjectCount()
{
return objectCount;
}
}
Don't use void
public Line(Point pointA, Point pointB)
{
pointA = new Point();
pointB = new Point();
}
Your Line class looks incomplete. It doesn't store any data. It should looks more like this:
class Line
{
public Point BottomRight { get; set; }
public Point Origin { get; set; }
public Line(Point pointA, Point pointB)
{
Origin = pointA;
BottomRight = pointB;
}
}
Then you need to only change line.BottomRight and line.Origin in GetLength method:
static double GetLength(Line line)
{
Point pointA = line.BottomRight;
Point pointB = line.Origin;
return pointA.DistanceTo(pointB);
}
This should work now

Making a method in a class that doesn't need to be called by an object of said class

I'm not really sure how to describe this question well, so apologies if this is hard to understand:
Just as a practice (I'm still quite new to C#) I wanted to make an class, Point, that worked like points on a coordinate grid. I have this so far:
using System;
using System.Collections.Generic;
using System.Text;
namespace Point_Class
{
class Point
{
private int x, y;
public Point()
{
Console.WriteLine("Default Constructor Loaded.");
this.x = 0;
this.y = 0;
}
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public string Equation(Point p1, Point p2)
{
}
}
class Program
{
static void Main(string[] args)
{
Point x,y;
x = new Point(2, 2);
y = new Point(5, 6);
x.DistanceTo(y);
Console.ReadLine();
}
}
}
Now, my question is this: Is there a way to run the Equation (function or method, unsure of terms) like this
Equation(Point x, Point y);
or does it have to be different?
Thanks.
Make it static:
class Point
{
public static string Equation(Point p1, Point p2)
{
...
}
}
Now you can call it with
var result = Point.Equation(x, y);

Categories