I want to call a constructor of a struct, that has default values for all parameters. But when I call the parameterless constructor of MyRectangle a not defined constructor get's called. Why is that? Is it possible to not have a not from me created constructor called?
using System;
namespace UebungClasses
{
class Program
{
static void Main(string[] args)
{
MyRectangle sixRec = new MyRectangle(3, 2);
MyRectangle oneRec = new MyRectangle();
Console.WriteLine("area of six: " + sixRec.Area() + " area of one: " + oneRec.Area());
}
}
public struct MyRectangle
{
public MyRectangle(double w = 1, double l = 1)
{
width = w;
length = l;
Console.WriteLine("Width: " + width + " Lenght: " + length);
}
public double Area()
{
return width * length;
}
private double width;
private double length;
}
}
You can't call a default constructor once you've created a constructor that takes arguments. You'll have to create the no argument constructor yourself in order to make a call from the parameterized constructor. Yes, this will work.
Note that if a constructor has any arguments that do not have default values, it is not a default constructor. The following example defines a class with one constructor and two default constructors. You can declare default constructors as explicitly defaulted functions or deleted functions.
It is possible to have a constructor with default arguments.. It means that if the constructor is defined with n parameters, we can invoke it with less than n arguments specified in the call.
If no constructors are explicitly declared in the class, a default constructor is provided automatically by the compiler. Can a default constructor contain a default argument? Yes, a constructor can contain default argument with default values for an object.
No, basically. If you use new MyRectangle()
, it will always prefer the default constructor (meaning: zero init in the case of struct
).
If you were dealing with integers, one potential workaround would be to use xor with your desired default in the property accessors - this would mean that when the fields are zero, you get the default values from the accessors. Unfortunately, to do this with double
would require using unsafe code to reinterpret the types.
One other potential solution would be to add a dummy parameter that you can use, for example:
new MyRectangle(dummy: true)
This dummy
parameter would do literally nothing except allow you to select the custom constructor.
Another final option would be to use a factory method (static MyRectangle Create(...)
) instead of the constructor.
The issue here is that the compiler will always resolve first to a valid constructor with no default parameters. Its a bit like with generics, where the non generic overload wins, well here, the non default parameter overload is preferred.
Because structs all have a parameterless constructor, that one will be chosen over yours.
A way around this if you need a different default rectangle could be:
public struct MyRectangle
{
private readonly bool isNotDefault;
public MyRectangle(double w, double l)
{
isNotDefault = true;
width = w;
length = l;
}
public double Area()
{
//Notice the use of the properties,
//not the backing fields.
return Width * Length;
}
private readonly double width, length;
public double Width => isNotDefault ? width: 1;
public double Length => isNotDefault ? length : 1;
public override string ToString()
=> $"Width: {Width} Lenght: {Length}";
}
Not sure I'd recommend this for a rectangle, after all a zero sized rectangle seems a reasonable choice, but there are cases where the default value really doesn't make sense. A clear example is a struct representing a rational number, where the default value is a mathematical indetermination: 0/0
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With