2013-01-14 16 views
5

Chciałbym przekazać podzbiór tablicy C# do metody. Nie obchodzi mnie, czy metoda nadpisuje dane, więc chciałbym uniknąć tworzenia kopii.C# Array slice bez kopii

Czy istnieje sposób, aby to zrobić?

Dzięki.

Odpowiedz

10

zmienić metodę do podjęcia się IEnumerable<T> lub ArraySegment<T>.

Następnie można przejść new ArraySegment<T>(array, 5, 2)

+0

Możesz dodać przykład 'IEnumerable ' z 'Skip' /' Take'. –

+1

@StefanSteinegger: 'ArraySegment ' implementuje 'IEnumerable ' – SLaks

+0

Świetne, dzięki. – user1400716

1

Tablice są niezmienne według rozmiaru (tj. Nie można zmienić rozmiaru tablicy), więc można przekazać tylko odjęta kopię oryginalnej tablicy. Jako opcję można przekazać dwa indeksy na bok oryginalnej tablicy do metody i działają na podstawie dodatkowych dwóch indeksów ..

-2

można używać LINQ wziąć Funktion i podjąć jak najwięcej elementów z tablicy, jak chcesz

var yournewarray = youroldarray.Take(4).ToArray(); 
+3

Jeśli dodasz 'ToArray' do końca, to wykonujesz kopię. Musisz także użyć 'Skip' i' Take', aby uzyskać dowolny podzbiór. Wreszcie, jeśli chce szybkiego dostępu indeksowanego w podzbiorze, nie uzyskałby go z 'IEnumerable'. – Servy

+0

-1: OP wyraźnie pisał, że nie chce mieć kopii. – Tom

2

Można stosować następujące klasy. Uwaga: może być konieczne zmodyfikowanie go w zależności od tego, czy chcesz, aby endIndex było włączone czy wyłączne. Można również zmodyfikować go, aby wziąć początek i liczbę, a nie indeks początkowy i końcowy.

Intencjonalnie nie dodawałem metod zmiennych. Jeśli specjalnie chcesz chcesz im, to jest dość łatwe, aby dodać. Możesz także zaimplementować IList, jeśli dodasz zmienne metody.

public class Subset<T> : IReadOnlyList<T> 
{ 
    private IList<T> source; 
    private int startIndex; 
    private int endIndex; 
    public Subset(IList<T> source, int startIndex, int endIndex) 
    { 
     this.source = source; 
     this.startIndex = startIndex; 
     this.endIndex = endIndex; 
    } 

    public T this[int i] 
    { 
     get 
     { 
      if (startIndex + i >= endIndex) 
       throw new IndexOutOfRangeException(); 
      return source[startIndex + i]; 
     } 
    } 

    public int Count 
    { 
     get { return endIndex - startIndex; } 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return source.Skip(startIndex) 
      .Take(endIndex - startIndex) 
      .GetEnumerator(); 
    } 

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