We have a struct called Vector3D
and for some methods we want the (default) zero vector as default argument but for others we want a different, non-default vector (say, a unit vector in x ditrection) as the default argument.
public struct Vector3D
{
public double X;
public double Y;
public double Z;
public Vector3D(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public static Vector3D UnitX()
{
return new Vector3D(1, 0, 0)
}
}
Now, a method with a zero vector as default argument can be easily achieved like this:
public void MyVectorMethod(Vector3D vec = new Vector3D())
{ ... }
However, if we want a different default argument (say, a unit vector in x-direction), the following does not work, because default arguments must be compile time constants:
public void MyVectorMethod(Vector3D vec = Vector3D.UnitX())
{ ... }
One way that we came up with was to use a nullable Vector3D
, like:
public void MyVectorMethod(Vector3D? vec = null)
{
Vector3D actualVec;
if (vec == null) actualVec = Vector3D.UnitX();
else actualVec = (Vector3D) vec;
...
}
This is equivalent to a unit vector in x-direction as the default argument. But the code is not very elegant and we have to add an extra type cast.
Is there a better (i.e., more elegant and without cast) way to achieve the same?
Edit: As Matthew suggested, a neat way would be to use a method overload with empty argument. However, in our project that approach is not always straightforward to apply, because the methods typically have multiple default arguments and we couple the library to a Python scripting interface with IronPython (which sometimes leads to issues with type guessing).
Consider for example a method like this ...
public void MyVectorMethod(Vector3D vec1 = new Vector3D(),
Vector3D vec2 = new Vector3D(), Vector3D vec3 = new Vector3D())
{ ... }
public void MyVectorMethod() => MyVectorMethod(Vector3D.UnitX());