2015-10-13 3 views
1

Как это сделать в данный момент:Есть ли лучший способ инкапсулировать массив?

class Foo 
{ 
    public int[] A { get { return (int[])a.Clone(); } } 
    private int[] a; 
} 

Я думаю, что это плохо, потому что это создает клон и отбрасывает всякий раз, когда я к нему доступ. Я знаю, что могу обойти это, введя дополнительную переменную, подобную этой:

var foo = new Foo(); 
// as soon as you have to access foo.A do this 
int[] fooA = foo.A; 
// use fooA instead of foo.A from now on 

но все же это просто выглядит плохо.

Я также не нравится Java способ инкапсулирования

int get(int index) { return a[index]; } 

, потому что я не получаю преимущества использования массива.

Есть ли лучший способ сделать это?

Редактировать: Я хочу массив инкапсулированных переменных. Проблема заключается в том, что

public int[] A { get; private set; } 

не является массив инкапсулированного переменными, потому что я могу изменить элементы массива из-за пределы класса.

редактировать: Он должен также работать с многомерными массивами

+5

На каких именно преимуществах вы смотрите? Возможно, вы можете добавить индексатора в 'Foo'. Боюсь, что неясно, чего вы пытаетесь достичь. –

+0

вы можете создать итератор для массива. но неясно, чего вы хотите достичь. –

+0

Я просто хочу массив инкапсулированных переменных – foxneSs

ответ

-1

звучит, как вам нужно индексатор

... 
public int this[int i]{ 
    get{return a[i];} 
    set{a[i] = value;} 
} 
.... 

https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

+1

За исключением «set», чтобы сделать его только для чтения? – 31eee384

+0

требования не ясны, я действительно ожидаю, что реальное решение не годится, читает или записывает в массив, но некоторый посреднический код. Я просто показываю синтаксис включения – pm100

+0

indexer не работал бы, если бы я хотел инкапсулировать более одного массива – foxneSs

0

в качестве альтернативы, можно использовать итератор/генератор для возврата элементов в соответствии с просьбой :

class Foo 
{ 
    public IEnumerable<int> A 
    { 
     get 
     { 
      foreach (int i in a) 
       yield return i; 
     } 
    } 
    private int[] a; 
} 

... th ан итерация над ними нормально или использовать LINQ, чтобы получить их в новый массив или другой тип коллекции:

int[] arr = foo.A.ToArray(); 
+1

Я должен отметить, что решение 'IReadOnlyList ' не решает проблему - возвращая массив в виде «IReadOnlyList », вы можете просто вернуть его обратно к 'int []' вне объекта, и у вас будет ссылка на исходный массив. После этого вы можете изменить содержимое до вашего сердца. – planetarian

+0

У кода была ошибка '(int i in A)', была исправлена. – planetarian

+0

Ну, если вы хотите быть педантичным, можно использовать отражение, чтобы получить поле массива итератора, возвращаемое этим объектом, и изменить его. В конце дня вы можете сделать так, чтобы кто-то не злоупотреблял собственной системой. Ни один из открытых публичных API решений не предоставляет изменяемых операций, и оба могут быть взломаны для поиска непубличных версий. На самом деле это просто иллюзия добавленной безопасности, без какой-либо дополнительной безопасности. – Servy

1

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

class Foo 
{ 
    public IReadOnlyList<int> A { get { return a; } } 
    private int[] a; 
} 
+0

Этот подход не работает, если массив является многомерным. – foxneSs

+0

@foxneSs А у вас многомерные массивы? Могут ли они быть реорганизованы в структуру данных другого типа, которые можно было бы более эффективно раскрывать в поместье только для чтения? Если вы ответили «да» и «нет» соответственно, тогда вам нужно создать свою собственную оболочку только для чтения, смоделированную после «IReadOnlyLIst», но с несколькими измерениями. – Servy

0

Почему бы не выставить в качестве реализации IReadOnlyList

class Foo 
{ 
    public IReadOnlyList<int> A { get { return a; } } 
    private int[] a; 
} 

Это позволяет возвращать массив как коллекцию, где они могут использовать индекс, но не может изменить содержимое самого массива.

Смежные вопросы