Как сделать двойной индексатор для собственного объекта класса в C#

Я создал новый класс для определения N-мерной матрицы на C#, однако, если я хочу получить доступ к ее элементам и не знаю, как действовать более чем с одним индексом. Элементы хранятся в массиве двойных массивов.

private class MatrixND
{
    private double[][] elements;
    public MatrixND()
    {
        elements = new double[N][];
    }
}

Обычно для доступа к индексу в собственном классе я добавляю в класс следующий метод:

public double this[int index]
{
    get
    {
        return elements[index];
    }
    set
    {
        elements[index] = value;
    }
}

Это сработало бы, если бы это был простой массив двойных чисел, тогда вызов индекса [i], где я может быть любым числом от 0 до длины массива, вернет двойное число.

Как мне сделать то же самое, но для моего матричного случая, чтобы я мог вызвать mymatrix[index1][index2] и получить дубль?

Большое спасибо!

Примечание: double[,] может быть более эффективным, если данные имеют прямоугольную форму.

Marc Gravell 04.06.2024 12:34

Извините, если я вас неправильно понял, прямоугольный означает одинаковое количество строк и столбцов? Если да, то в данном случае да, но в будущем я хотел бы расширить его до другого количества столбцов и строк.

Lluis 04.06.2024 12:40

Да, прямоугольный здесь будет означать, что каждая строка имеет одинаковую длину (или, альтернативно и эквивалентно: каждый столбец имеет одинаковую высоту)

Marc Gravell 04.06.2024 12:43

Просто вернуть двойной [] вместо простого двойного из вашего индексатора?

Ralf 04.06.2024 12:57

Если вы пойдете по маршруту double[], не забудьте удалить установщик индексатора, который вам не нужен.

Ralf 04.06.2024 13:17

Что собираешься делать с mymatrix[index1][index2] ? Это просто значение или вы хотите получить доступ к внутренним функциям mymatrix? Рассмотрите возможность возврата оболочки из индексатора, которая берет текущий основной экземпляр и расширяет его необходимыми функциями, например. матрица[i] -> строка, строка[i] -> ячейка и т. д.

Sinatr 04.06.2024 13:32

@Ральф, ты хочешь опубликовать свой ответ? Я приму это, потому что это было буквально то, чего я хотел! Оказалось, что я был почти у цели, но, клянусь, я не осознавал, что это настолько очевидно, хе-хе

Lluis 05.06.2024 17:23

@Lluis, я не гонюсь за репутацией. Я уже рад, что смог быть полезен.

Ralf 05.06.2024 17:27

Хорошо, тогда я приму вариант Марка и предложу включить ваш вариант, еще раз спасибо!

Lluis 05.06.2024 17:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы используете public double this[int x, int y], вызывающая сторона может получить доступ к obj[7, 12] и т. д. Однако для доступа obj[7][12] потребуется, чтобы первый индексатор возвращал тип, который сам имеет другой индексатор - возможно, struct, который просто содержит родительский экземпляр и первое значение индекса, эффективно откладывая полное поиск до тех пор, пока не будет указан второй индекс.


Что-то вроде:

public sealed class MatrixND
{
    private const int N = 42; // or a a.ctor arg, whatever
    private double[][] elements;
    public MatrixND()
    {
        elements = new double[N][];
    }

    public Indexer this[int x] => new(this, x);

    public readonly struct Indexer(MatrixND parent, int x)
    {
        public double this[int y]
        {
            get => parent.elements[x][y];
            set => parent.elements[x][y] = value;
        }
    }
}

Другие вопросы по теме