Ограниченная реализация IList <>? - PullRequest
1 голос
/ 12 апреля 2010

Я работаю со статистикой и хочу изменить метод следующим образом:

public static blah(float[] array)
{
    //Do something over array, sum it for example.
}

Однако вместо использования float [] я хотел бы использовать какой-то индексированный перечисляемый тип (например, динамическую загрузку с диска для очень больших массивов). Я создал простой интерфейс и хотел его использовать.

public interface IArray<T> : IEnumerable<T>
{
    T this[int j] { get; set; }
    int Length { get; }
}

Моя проблема:

  • float [] наследует только IList, а не IArray, и AFAIK, изменить это невозможно.
  • Я бы хотел отказаться от IArray и использовать только IList, но мои классы должны были бы реализовать много методов, таких как Add, RemoveAt, хотя они фиксированного размера
  • И тогда мой вопрос: как float [] может реализовать IList, тогда как у него нет этих методов?

Любая помощь приветствуется. Приветствия

Ответы [ 3 ]

2 голосов
/ 12 апреля 2010

float [] наследует только IList, а не IArray, и AFAIK, изменить это невозможно.

Массив T также реализует IList<T> и другие (но они не всегда отображаются в инструментах, некоторые аспекты массива как особые, учитываемые средой выполнения).

Я бы хотел отказаться от IArray и использовать только IList, но мои классы должны были бы реализовать много методов [...]

Это правда, но такая реализация выполняется довольно быстро (и если вам нужны только немодифицирующие операции, вы можете просто выбросить NotImplementedException из модифицирующих методов).

На практике это занимает всего несколько минут, и ваша реализация должна быть многоразовой. Также есть такие типы, как ReadOnlyCollection<T>, чтобы помочь избежать этой работы.

И тогда мой вопрос: как float [] может реализовать IList, тогда как у него нет этих методов?

Тип может явно реализовывать методы интерфейса. Они не являются непосредственно членами типа, но приведение к интерфейсу (или отражение) позволит получить доступ. Это позволяет типизированной коллекции реализовать IEnumerator.Current (возвращая Object), а также предоставляет свойство Current, которое возвращает правильный тип.

1 голос
/ 12 апреля 2010

Фактически, float[] array реализует IList<float>:

var floats = new[] { 1.0f, 2.0f, 3.5f };
var list = (IList<float>)floats;

Это за 19,6 :

Одномерный массив S[] реализует интерфейс System.Collections.Generic.IList<S> (для краткости IList<S>) и его базовые интерфейсы. Соответственно, существует неявное преобразование из S[] в IList<S> и его базовые интерфейсы.

0 голосов
/ 12 апреля 2010

Я закончил писать следующие вещи: открытый класс IArrayWrapper: IArray {private float [] innerArray;

    public IArrayWrapper(float[] array)
    {
        innerArray = array;
    }

    public static implicit operator float[](IArrayWrapper wrapper)
    {
        return wrapper.innerArray;
    }

    public static implicit operator IArrayWrapper(float[] array)
    {
        return new IArrayWrapper(array);
    }

    public IEnumerator<float> GetEnumerator()
    {
        return ((IEnumerable<float>) innerArray).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return innerArray.GetEnumerator();
    }

    public float this[int j]
    {
        get { return innerArray[j]; }
        set { innerArray[j] = value; }
    }

    public int Length
    {
        get { return innerArray.Length; }
    }
}

Я не очень горжусь этим, но я думаю, что неявные операторы должны решить мою проблему... надеюсь.

...