Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用默认值初始化结构,返回null(自定义Matrix4结构)_C# - Fatal编程技术网

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

C# 使用默认值初始化结构,返回null(自定义Matrix4结构),c#,C#,我正在创建自己的Matrix4x4结构,但问题是,如果我在创建新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);

我正在创建自己的Matrix4x4结构,但问题是,如果我在创建
新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

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

public readonly struct Mat4x4 
{

    private Mat4x4()
    {
    }

    ...
}

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

您可以通过
矩阵
属性将空数组视为等同于
标识
中的数组,该属性在代码中的任何地方都会使用

公共只读结构Mat4x4
{
公共静态Mat4x4标识{get;}=新的Mat4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
//仅存储-可能为空。
私有只读双[]矩阵;
//在任何地方使用它,它将永远不会为空。
私有双[]矩阵=>矩阵??Identity.Matrix;
公共Mat4x4(双m00=1,双m01=0,双m02=0,双m03=0,双m10=0,双m11=1,双m12=0,双m13=0,双m20=0,双m21=0,双m22=1,双m23=0,双m30=0,双m31=0,双m32=0,双m33=1)
{
矩阵=新的双[]{m00、m01、m02、m03、m10、m11、m12、m13、m20、m21、m22、m23、m30、m31、m32、m33};
}
public double this[int row,int column]=>矩阵[row*4+column];
公共重写字符串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]}]”;
}

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

不,您不能在结构中声明无参数构造函数。是的,这是我已经尝试过的,可能应该提到的,但这不适用于结构。这正是我想要的工作方式,但是,这样做会带来额外的性能成本吗?我认为它本质上是在做一个
if matrix==null return Identity,else return matrix
检查每次你访问一个值吗?@PatrikFröhler:是的,它会这样做。这会影响性能,但这是否重要取决于您的应用程序。假设您的结构实际上有多个其他方法,在每种方法中,您可能希望在多次使用属性值之前获取属性值的本地副本。嗯,在这种情况下,我可能需要重新考虑一下,我目前正在重新编写旧的Matrix4,以尝试提高性能,我假设,当我想在一个方法中使用值时,必须复制一个矩阵,这也会带来一些性能成本。我可能会尝试不使用双数组并单独存储值,但访问变得很棘手,如果你有其他建议,我会很高兴听到它们。@PatrikFröhler:同样值得注意的是,虽然你的单位矩阵是乘法的自然默认值,对于其他事情,比如加法,它绝对不是一个好的默认值。这有点像将
int
变量默认为1。您可能只想保持原样,并接受默认值无效。我创建了一个不使用数组的版本(请参见编辑),是的,它将默认为0,可能更好,然后,如果我想将其作为标识,我必须显式地将其设置为
=Mat4x4.Identity
我查看了我的旧Matrix4x4结构,实际上我没有在任何点循环遍历这些值,所以我实际上不需要索引器。为什么
结构
?使用
class
和无参数构造函数。