Инициализировать структуру со значениями по умолчанию, возвращает ноль (пользовательская структура Matrix4x4) - PullRequest
1 голос
/ 26 марта 2020

Я создаю свою собственную структуру Matrix4x4, но проблема у меня заключается в том, что если я не укажу ему значения параметра при создании new Mat4x4(), тогда он будет нулевым, вместо того, чтобы установить его по умолчанию При просмотре параметров в режиме отладки он временно устанавливает значения в конструкторе, но затем возвращается к нулю.

Код структуры:

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

* 1019. * РЕДАКТИРОВАТЬ:

Пропуск использования 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

Ответы [ 2 ]

3 голосов
/ 26 марта 2020

Вы не можете сделать это - по крайней мере, не очень простым способом. new Mat4x4 всегда будет инициализировать каждое поле значением по умолчанию - которое равно null для любого ссылочного типа, включая массивы.

То, что вы можете сделать, это обработать нулевой массив как эквивалентный значение в Identity через свойство Matrix, которое используется везде в коде.

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

Обратите внимание, что свойство все еще является частным и должно быть - в противном случае массив может быть видоизменён.

0 голосов
/ 26 марта 2020

Вы можете объявить свой собственный конструктор по умолчанию:

public readonly struct Mat4x4 
{

    private Mat4x4()
    {
    }

    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...