2010-04-12 3 views
1

Я делаю некоторые работы со статистикой, и хочу, чтобы реорганизовать следующий метод:Ограниченная реализация IList <>?

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

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

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

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

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

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

ответ

2

поплавок [] только наследует IList, а не IArray, и AFAIK нет никакого способа, чтобы изменить это.

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

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

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

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

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

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

+0

Думаю, вы имеете в виду явное, неявное – Sekhat

+0

@ Sekhat: действительно, я это сделал. Исправленный. – Richard

+0

Хм, спасибо, вы узнали мне разницу между реализацией метода явного/неявного интерфейса. – Wam

1

В самом деле, 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

Я знаю, что мой вопрос заключается в том, может ли он реализовывать IList и ICollection без реализации Add, RemoveAt и других методов от ICollection/IList? – Wam

0

Я закончил тем, что писал следующее вещество: общественный класс IArrayWrapper: IArray { частное поплавок [] 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; } 
    } 
} 

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