Tworzę własną strukturę Matrix4X4, ale problem, który mam, jest, jeśli nie podawę jej żadnych wartości dla parametru, gdy utworzę new Mat4x4(), to będzie null, a następnie ustawić go do domyślnych parametrów , gdy patrząc na to w trybie debugowania tymczasowo ustawia wartości w konstruktorze, ale następnie wraca do NULL.

Kod struktury:

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;
    }
}

Spowoduje to rzucenie błędu, ponieważ matrix = null:

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

Ale to będzie działać i ustawić matrycę do poprawnych wartości domyślnych:

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

Sposób, w jaki go chcę, jest to, że jeśli nie podadzę jej żadnych parametrów, powinno ustawić wartości do tego samego, co Identity, również chcę mieć opcję, aby ustawić tylko wybrane wartości, takie jak {{x1} } I nadal masz resztę ustawioną na Identity

EDYTUJ:

Pomijanie użycia 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() domyślnie jest 0,0,0,0 ... i dla matrycy tożsamości var myMat = Mat4x4.Identity

c#
1
Patrik Fröhler 26 marzec 2020, 14:49

2 odpowiedzi

Najlepsza odpowiedź

Nie możesz tego zrobić - przynajmniej nie w bardzo prosty sposób. new Mat4x4 zawsze zainicjuje każde pole do wartości domyślnej - który jest null dla dowolnego typu odniesienia, w tym tablic.

Co może , to traktować tablicę zerową jako równoważną z Identity przez właściwość Matrix, która jest używana wszędzie w kodzie.

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]} ]";
}

Należy pamiętać, że nieruchomość jest nadal prywatna i musi być - w przeciwnym razie tablica może być zmutowana.

3
Jon Skeet 26 marzec 2020, 11:59

Możesz zadeklarować własny domyślny konstruktor domyślny:

public readonly struct Mat4x4 
{

    private Mat4x4()
    {
    }

    ...
}
-1
Martin Staufcik 26 marzec 2020, 11:58