使用默认值初始化结构,返回null(自定义Matrix4x4结构)



我正在创建我自己的Matrixx4x4结构,但我遇到的问题是,如果我在创建new Mat4x4()时不给它任何参数值,那么它将为null,而不是将其设置为默认参数,在调试模式下查看它时,它会在构造函数中临时设置值,但随后会返回null。

结构代码:

public readonly struct Mat4x4
{
public static Mat4x4 Identity { get; } = new Mat4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
private readonly double[] matrix;
public Mat4x4(double m00 = 1, double m01 = 0, double m02 = 0, double m03 = 0, double m10 = 0, double m11 = 1, double m12 = 0, double m13 = 0, double m20 = 0, double m21 = 0, double m22 = 1, double m23 = 0, double m30 = 0, double m31 = 0, double m32 = 0, double m33 = 1)
{
matrix = new double[] { m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33 };
}
public double this[int row, int column]
{
get
{
return (matrix[row * 4 + column]);
}
}
public override string ToString()
{
string str = $"[ {matrix[0]} , {matrix[1]} , {matrix[2]} , {matrix[3]} ]n" +
$"[ {matrix[4]} , {matrix[5]} , {matrix[6]} , {matrix[7]} ]n" +
$"[ {matrix[8]} , {matrix[9]} , {matrix[10]} , {matrix[11]} ]n" +
$"[ {matrix[12]} , {matrix[13]} , {matrix[14]} , {matrix[15]} ]";
return str;
}
}

这将引发一个错误,因为matrix = null:

Mat4x4 testMatrix = new Mat4x4();
Debug.Log(testMatrix.ToString());

但这将起作用,并将矩阵设置为正确的默认值:

Mat4x4 testMatrix = new Mat4x4(m00:1);
Debug.Log(testMatrix.ToString());

我希望它的工作方式是,如果我不给它任何参数,它应该将值设置为与Identity相同,而且我希望可以选择只设置选定的值,如new Mat4x4(m02:2,m13:5),其余的仍设置为Identity

编辑:

跳过double[]的使用

public readonly struct Mat4x4
{
public static Mat4x4 Identity { get; } = new Mat4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public double M00 { get; }
public double M01 { get; }
public double M02 { get; }
public double M03 { get; }
public double M10 { get; }
public double M11 { get; }
public double M12 { get; }
public double M13 { get; }
public double M20 { get; }
public double M21 { get; }
public double M22 { get; }
public double M23 { get; }
public double M30 { get; }
public double M31 { get; }
public double M32 { get; }
public double M33 { get; }
public Mat4x4(double m00 = 0, double m01 = 0, double m02 = 0, double m03 = 0, double m10 = 0, double m11 = 0, double m12 = 0, double m13 = 0, double m20 = 0, double m21 = 0, double m22 = 0, double m23 = 0, double m30 = 0, double m31 = 0, double m32 = 0, double m33 = 0)
{
M00 = m00; M01 = m01; M02 = m02; M03 = m03;
M10 = m10; M11 = m11; M12 = m12; M13 = m13;
M20 = m20; M21 = m21; M22 = m22; M23 = m23;
M30 = m30; M31 = m31; M32 = m32; M33 = m33;
}
public double this[int row, int column]
{
get
{
return this[row * 4 + column];
}
}
public double this[int index]
{
get
{
switch (index)
{
case 0: return M00;
case 1: return M01;
case 2: return M02;
case 3: return M03;
case 4: return M10;
case 5: return M11;
case 6: return M12;
case 7: return M13;
case 8: return M20;
case 9: return M21;
case 10: return M22;
case 11: return M23;
case 12: return M30;
case 13: return M31;
case 14: return M32;
case 15: return M33;
default: return M00;
}
}
}
public override string ToString() =>
$"[ {M00} , {M01} , {M02} , {M03} ]n" +
$"[ {M10} , {M11} , {M12} , {M13} ]n" +
$"[ {M20} , {M21} , {M22} , {M23} ]n" +
$"[ {M30} , {M31} , {M32} , {M33} ]";
}

var myMat = new Mat4x4()将默认为0,0,0,0…并且对于单位矩阵var myMat = Mat4x4.Identity

你不能这样做——至少不是用一种非常简单的方式。new Mat4x4将始终将每个字段初始化为默认值——对于任何引用类型(包括数组(,该值都是null

可以通过Matrix属性将空数组视为等效于Identity中的空数组,该属性在代码中的各处都使用。

public readonly struct Mat4x4
{
public static Mat4x4 Identity { get; } = new Mat4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
// Storage only - might be null.
private readonly double[] matrix;
// Use this everywhere, and it will never be null.
private double[] Matrix => matrix ?? Identity.matrix;
public Mat4x4(double m00 = 1, double m01 = 0, double m02 = 0, double m03 = 0, double m10 = 0, double m11 = 1, double m12 = 0, double m13 = 0, double m20 = 0, double m21 = 0, double m22 = 1, double m23 = 0, double m30 = 0, double m31 = 0, double m32 = 0, double m33 = 1)
{
matrix = new double[] { m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33 };
}
public double this[int row, int column] => Matrix[row * 4 + column];
public override string ToString() =>
$"[ {Matrix[0]} , {Matrix[1]} , {Matrix[2]} , {Matrix[3]} ]n" +
$"[ {Matrix[4]} , {Matrix[5]} , {Matrix[6]} , {Matrix[7]} ]n" +
$"[ {Matrix[8]} , {Matrix[9]} , {Matrix[10]} , {Matrix[11]} ]n" +
$"[ {Matrix[12]} , {Matrix[13]} , {Matrix[14]} , {Matrix[15]} ]";
}

请注意,该属性仍然是私有的,并且需要是私有的——否则数组可能会发生变异。

您可以声明自己的私有默认构造函数:

public readonly struct Mat4x4 
{
private Mat4x4()
{
}
...
}

最新更新