在c++中,我可以这样做
class CVector3D {
public:
float x, y, z;
CVector3D (float x = 0.0f, float y = 0.0f, float z = 0.0f) : x(x), y(y), z(z) {}
CVector3D (CVector3D const& other) { x = other.x, y = other.y, z = other.z; }
};
class CMatrix3D {
public:
CVector3D r, u, f;
CMatrix (r = CVector3D (1.0f, 0.0f, 0.0f),
u = CVector3D (0.0f, 1.0f, 0.0f),
f = CVector3D (0.0f, 0.0f, 1.0f))
: r(r), u(u), f(f) {}
};
在c#中,我尝试了:
public class CVector3D
{
public (float x, float y, float z) coords;
public CVector3D (float x = 0.0f, float y = 0.0f, float z = 0.0f) => coords = (x,y,z);
}
public class CMatrix3D
{
public (CVector3D r, CVector3D u, CVector3D f) dirs;
// variant 1.1
public CMatrix3D (CVector3D r = CVector3D (1.0f, 0.0f, 0.0f),
CVector3D u = CVector3D (0.0f, 1.0f, 0.0f),
CVector3D f = CVector3D (0.0f, 0.0f, 1.0f))
{
dirs.r = r;
dirs.u = u;
dirs.f = f;
}
// variant 1.2
public CMatrix3D (CVector3D r = new CVector3D (1.0f, 0.0f, 0.0f),
CVector3D u = new CVector3D (0.0f, 1.0f, 0.0f),
CVector3D f = new CVector3D (0.0f, 0.0f, 1.0f))
{
dirs.r = r;
dirs.u = u;
dirs.f = f;
}
// variant 2
public CMatrix(
ValueTuple<float, float, float> r = (1.0f, 0.0f, 0.0f),
ValueTuple<float, float, float> u = (0.0f, 1.0f, 0.0f),
ValueTuple<float, float, float> f = (0.0f, 0.0f, 1.0f))
{
dirs.r = r;
dirs.u = u;
dirs.f = f;
}
}
两个都不行。我知道我需要做一些像
这样的事情我该如何去做我想要的?
正如编译器所说:默认值必须可表示为编译时常量,这不是。您可以使用null
值暗示这些值,即
public CMatrix3D(CVector3D r = null,
CVector3D u = null,
CVector3D f = null);
{
dirs.r = r ?? new CVector3D(1.0f, 0.0f, 0.0f);
dirs.u = u ?? new CVector3D(0.0f, 1.0f, 0.0f);
dirs.f = f ?? new CVector3D(0.0f, 0.0f, 1.0f);
}
然而,我想说这实际上是readonly struct
(两种类型)的主要情况,而不是class
。然后,我可能只是有一个静态的Identity
属性,返回单位矩阵。我可能也不会在这里使用ValueTuple
。
我的意思的例子(注意:使用c# 10的特性):
using System;
var original = Matrix3D.Identity;
Console.WriteLine(original);
// show manipulation (note: you could also update the original value like this)
var delta = original with { F = new (2,2,2)};
Console.WriteLine(delta);
// to show tuple decomposition
Console.WriteLine(delta.F); // uses our type's ToString
var (r, u, f) = delta.F;
Console.WriteLine($"r={r}, u={u}, f={f}"); // do it ourselves
// record structs are C# 10, note!
readonly record struct Vector3D(float X, float Y, float Z)
{
public static Vector3D Zero => new();
public override string ToString()
=> $"({X}, {Y}, {Z})";
}
readonly record struct Matrix3D(Vector3D R, Vector3D U, Vector3D F)
{
public static Matrix3D Zero { get; } = new();
public static Matrix3D Identity { get; } = new(new(1, 0, 0), new(0, 1, 0), new(0, 0, 1));
public override string ToString()
=> $"[{R}, {U}, {F}]";
}