I got a question about constructors for my Windows Forms Application. First of all I want to say that I am new to programming.
The thing is this. I am making a constructor in another class that should hold different parameter values. In this case it should be int X, int Y, int Length, int Height. What I want to do here is to make the X, Y, Length and Height all random for my picturebox. I send code down below:
class Rechthoekcs
{
Random random = new Random();
public int Xas
{
get;
set;
}
public int Yas
{
get;
set;
}
public int Lengte
{
get;
set;
}
public int Breedte
{
get;
set;
}
public Rechthoekcs(int x, int y, int lengte, int breedte)
{
this.Xas = x;
this.Yas = y;
this.Lengte = lengte;
this.Breedte = breedte;
x = random.Next(x);
y = random.Next(y);
lengte = random.Next(lengte);
breedte = random.Next(breedte);
}
From my Form1 I want to call this class/constructor
But it gives me an error. It says "Does not contain a constructor with 0 arguments" and I know that because I typed the x, y, length and width. But I cannot add just the variables from the other class into the new parameter. I really don't get it. I find constructors very hard. I never know what parameters I should give with it...
I send the code down below from my Form1:
public partial class Form1 : Form
{
Rechthoekcs Rechthoek = new Rechthoekcs(.......);
public Form1()
{
InitializeComponent();
}
It it really frustrating for me. I tried looking up on the web and books and such but all the explanation about which parameters should be given for a constructor is not clear to me. Could someone explain this? Not understanding it drives me insane. Plus I am getting often stuck at these points..
public Rechthoekcs(int x, int y, int lengte, int breedte)
{
this.Xas = x;
this.Yas = y;
this.Lengte = lengte;
this.Breedte = breedte;
x = random.Next(x);
y = random.Next(y);
lengte = random.Next(lengte);
breedte = random.Next(breedte);
}
You are assigning the values of the parameters to your private Data Members before you do anything "randomizing" about them. You are simply changing the values of the parameters in your constructor without assigning them. Swap the order you do them in.
public Rechthoekcs(int x, int y, int lengte, int breedte)
{
x = random.Next(x);
y = random.Next(y);
lengte = random.Next(lengte);
breedte = random.Next(breedte);
this.Xas = x;
this.Yas = y;
this.Lengte = lengte;
this.Breedte = breedte;
}
Now you have successfully randomized your values that will be set to your data member variables ASSUMING that those variable you put in there actually exist, which they should. Better/more modular code would do this randomization where you create your object.
Ex: Object foo = new Object(new Random, new Random, new Random, new Random)
Not the answer OP is looking for, but this is how you solve "I don't yet know the value but I need to construct object anyway" version of the question.
You can delay requesting the data by passing Func<T> for each parameter instead of just T assuming the values actually will be available by the time they needed:
class UseDelayedValues
{
Func<int> x;
public UseDelayedValues(Func<int> x)
{
this.x = x;
}
public UseWithX(int other)
{
return other + x();
}
}
int value = 0;
var r = new UseDelayedValues(() => value);
value = 42;// get some value
Console.WriteLine(r.UseDelayedValues(1));
var delayedFromTextbox = new UseDelayedValues(() => int.Parse(textBox1.Value));
Lines using the UseDelayedValues can be spread over time. I.e. instance constructed in constructor, but value used only when form is shown by button click.
Related
This question already has answers here:
C# 3.0 Auto-Properties - Is it possible to add custom behaviour?
(6 answers)
Closed 1 year ago.
I have the following class with auto properties:
class Coordinates
{
public Coordinates(int x, int y)
{
X = x * 10;
Y = y * 10;
}
public int X { get; set; }
public int Y { get; set; }
}
As you can see from the constructor I need the value to be multiplied by 10.
Is there anyway to do it without removing autoproperties?
I tried the following not thinking that it causes recursion and then everything goes fubar
public int X { get {return X;} set{ X *= 10;} }
I would like to assign values to X and Y multiplied by 10.
Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 7 to X but I would like it to be 70.
In order to make setter working like that, you'll need to use backing field:
class Coordinates
{
public Coordinates(int x, int y)
{
X = x;
Y = y;
}
private int _x;
public int X
{
get { return _x; }
set { _x = value * 10; }
}
private int _y;
public int Y
{
get { return _y; }
set { _y = value * 10; }
}
}
Given your example:
Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 70
However, I don't recommend you having such setter because it could lead to confusion. It's better to have a dedicated method which will do such multiplication. In the end, your code will be more descriptive and intuitive.
You get a recursion, because you again call the same property, which in turn calls the same property, which in turn calls the same property... you get the point.
public int X { get {return X;} set{ X *= 10;} }
How does auto properties works ?
Behind the scenes Properties are actually methods, which means they don't actually store data. So who saves the data ? AutoProperties generate private backend field to save the data.
So in the simple declaration of auto property
int X { get; set; }
The compiler translate it into something like that
private int <X>k__BackingField;
public int X
{
[CompilerGenerated]
get
{
return <X>k__BackingField;
}
[CompilerGenerated]
set
{
<X>k__BackingField = value;
}
}
So no matter if you use it as Auto Properties or simple property, they are the same.
Now, to answer you question, with paraphrasing, "How do i return the value multiply with 10"
You can solve it with using 2 ways:
1. By saving the data multiply by 10 (setter implementation)
2. By returning the data multiply by 10 (getter implementation)
I won't elavorate, which one you should use, because for this kind of simple scenario, both will be perfectly valid.
I would just say that some of the factors for the choice will be micro(micro micro micro) performence, true state storage.
Here is the setter implementation
private int _x;
public int X
{
get
{
return _x;
}
set
{
return _x*10;
}
}
So I'm creating a Snake-game and want to test that the "Snake-food" changes Position when "eaten".
So I have a simple Position-class that looks kinda like this:
public class Position
{
public int XCoordinate {get; set;}
public int YCoordinate {get; set;}
public Position(int x, int y)
{
XCoordinate = x;
YCoordinate = y;
}
}
And in the test, I want to see that the Position of the food updates when eaten. Because there seems to be no good way of comparing objects, I'm doing this with Assert like this(simplified method):
[Test]
public void AssertFoodSpawnsOnNewLocationWhenEaten()
{
int expectedX = _sut.Food.Pos.XCoordinate;
int expectedY = _sut.Food.Pos.YCoordinate;
_sut.FeedSnake();
int resultX = _sut.Food.Pos.XCoordinate;
int resultY = _sut.Food.Pos.YCoordinate;
Assert.AreNotEqual(expectedX, resultX);
Assert.AreNotEqual(expectedY, resultY);
}
Realized that my solution is a bad one, since the Food-Position could have been updated even tough e.g. expectedX and resultXare equal.
Does anyone have a tip how I could test this? Can you do some kind of Assert.AreNotEqual checking if both x-and y-coordinates are not equal?
Thankful for any help!
Made a separate private function that determines if the x and y coordinates are the same. This checks if _sut.FeedSnake()updates the Food-position when eaten.
[Test]
public void AssertFoodSpawnsOnNewLocationWhenEaten()
{
Position expected = _sut.Food.Pos;
_sut.FeedSnake();
Position result = _sut.Food.Pos;
Assert.False(IsPositionEqual(expected, result));
}
private bool IsPositionEqual(Position Pos1, Position Pos2)
{
if (Pos1.XCoordinate == Pos2.XCoordinate &&
Pos1.YCoordinate == Pos2.YCoordinate)
{
return true;
}
return false;
}
I have a custom list that contains custom classes that each contain 3 integer variables (x, y, height). I want to be able to search the listed elements for any that match both 'x,y' and then return 'height' in the instance I don't know what 'height' currently is, only the current x/y.
This is the custom class
public class ConstructionCoordinates
public int x;
public int y;
public int height;
public ConstructionCoordinates(int xCoord, int yCoord, int levelHeight)
{
x = xCoord;
y = yCoord;
height = levelHeight;
}
This is the Custom List
public List<ConstructionCoordinates> constructionCoordList = new List<ConstructionCoordinates>();
foreach (ConstructionCoordinates constructionCoord in constructionCoordList) {
if (constructionCoord.x == x && constructionCoord.y == y) {
// Place your logic here
}
}
I have mini class, which I save in List. Now I must delete in list, lines where numRect = -1. How can I do it?
double pointX, pointY;
int numRect;
public PointsSelectedSources(double x, double y, int numRect)
{
pointX = x;
pointY = y;
this.numRect = numRect;
}
public int NumRect
{
get
{
return numRect;
}
set
{
numRect = value;
}
}
Let miniClassList be the List then you can do something like the following to remove all objects from that list which are having numRect = -1;
miniClassList.RemoveAll(x=> x.numRect == -1);
Working example for more clarification
Hey I want to have something like that
int a=0;
a=5(be unchangeable);
a=3;
Console.WriteLine(a);//which will print 5 and not 3
so basically make declare the variable a number and have it be final and unchangeable, I tried looking around but I only found things that work as the int is declared and not as a new value for it is declared.
doesn't this work?
const int a = 5;
see const(C# reference)
const int a = 0;
The const keyword is used to modify a declaration of a field or local
variable. It specifies that the value of the field or the local
variable is constant, which means it cannot be modified.
Ref.
You want the const keyword.
const int a = 5;
From MSDN:
The const keyword is used to modify a declaration of a field or local variable. It specifies that the value of the field or the local variable cannot be modified.
EDIT: Your requirement sounds odd and not useful. But if you really need it, you'll have to create a custom type. I'd suggest a class with a bool property stating whether or not it's mutable or not.
public class MyCustomInt
{
public bool IsMutable { get; set; }
private int _myInt;
public int MyInt
{
get
{
return _myInt;
}
set
{
if(IsMutable)
{
_myInt = value;
}
}
}
public MyCustomInt(int val)
{
MyInt = val;
IsMutable = true;
}
}
Then when you use it:
MyCustomInt a = new MyCustomInt(0);
a.MyInt = 5;
a.IsMutable = false;
a.MyInt = 3; //Won't change here!
Console.WriteLine(a); //Prints 5 and not 3
That's about as good as you can get, I think.
use readonly:
as it can be changed by the constructor but then not again.
public class MyClass {
private readonly int a = 0;
public MyClass(int a) {
this.a = a;
}
public void DoSomethingWithA() {
Console.WriteLine(this.a);
//a = 5 // don't try this at home kids
}
}
new MyClass(5).DoSomethingWithA();
A nice comparison between const and readonly
You can use a constant with the const keyword.
const int a = 5;
but if you do that, you will not be allowed to change to another value.
You also can check the use of the pointers:
int x = 5;
int y = 3;
int *ptr1 = &x; // point to x memory address
int *ptr2 = &y; // point to y memory address
Console.WriteLine(x); // print 5
Console.WriteLine(y); // print 3
Console.WriteLine((int)ptr1); // print 5
Console.WriteLine((int)ptr2); // print 3
Console.WriteLine(*ptr1); // print 5
Console.WriteLine(*ptr2); // print 3
* char identify a pointer and & specify the memory address. But you should take care with pointers because unlike reference types, pointer types are not tracked by the default garbage collection mechanism.