Pobieranie pod-tablicy z istniejącej tablicy


335

Mam tablicę X zawierającą 10 elementów. Chciałbym utworzyć nową tablicę zawierającą wszystkie elementy z X, które zaczynają się od indeksu 3, a kończą na indeksie 7. Jasne, że mogę łatwo napisać pętlę, która to zrobi za mnie, ale chciałbym zachować mój kod tak czysty, jak to możliwe . Czy istnieje metoda w C #, która może to dla mnie zrobić?

Coś w stylu (pseudo kod):

Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)

Array.Copynie pasuje do moich potrzeb . Potrzebuję elementów z nowej tablicy, aby były klonami. Array.copyto tylko memcpyodpowiednik w stylu C. Nie szukam tego.



7
@Kirtan - ten „dup” konkretnie chce IEnumerable <T> - który jest inny i ma inne optymalne rozwiązania; IMO
— Marc Gravell

Tak więc, dwa wiersze potrzebne do zadeklarowania nowej tablicy i wywołania .Copy () nie są „czystym kodem”?
— Ed S.

2
@Ed Swangren - nie, jeśli musisz to zrobić w środku przykuty wyrazem, nie ;-p
— Marc Gravell

2
Odpowiedź ShaggyUka ​​jest prawdopodobnie poprawna: stackoverflow.com/questions/943635/...
— Dykam

Odpowiedzi:


469

Możesz dodać go jako metodę rozszerzenia:

public static T[] SubArray<T>(this T[] data, int index, int length)
{
    T[] result = new T[length];
    Array.Copy(data, index, result, 0, length);
    return result;
}
static void Main()
{
    int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int[] sub = data.SubArray(3, 4); // contains {3,4,5,6}
}

Zaktualizuj klonowanie (co nie było oczywiste w pierwotnym pytaniu). Jeśli naprawdę chcesz głębokiego klona; coś jak:

public static T[] SubArrayDeepClone<T>(this T[] data, int index, int length)
{
    T[] arrCopy = new T[length];
    Array.Copy(data, index, arrCopy, 0, length);
    using (MemoryStream ms = new MemoryStream())
    {
        var bf = new BinaryFormatter();
        bf.Serialize(ms, arrCopy);
        ms.Position = 0;
        return (T[])bf.Deserialize(ms);
    }
}

Wymaga to jednak możliwości serializacji ( [Serializable]lub ISerializable) obiektów. Można łatwo zastąpić każdy inny serializatora jako właściwy - XmlSerializer, DataContractSerializer, protobuf netto itp

Zauważ, że głęboki klon jest trudny bez serializacji; w szczególności ICloneabletrudno jest zaufać w większości przypadków.


1
(oczywiście użycie indeksu końcowego zamiast długości jest prostą zmianą; opublikowałem „tak jak jest”, ponieważ jest to bardziej „typowe” użycie)
— Marc Gravell

1
Potem ... twardy; nie robi tego .... prawdopodobnie trzeba by użyć serializacji, aby osiągnąć coś podobnego
— Marc Gravell

1
zobacz moją odpowiedź na kilka alternatyw i link do kilku implementacji. część robienia tego z podrzędną tablicą jest naprawdę dość trywialna, tak naprawdę chcesz bitu klonującego i jest to złożone i nieco otwarte pytanie, które zależy całkowicie od twoich oczekiwań co do tego, jakie „prawidłowe” powinno być zachowanie .
— ShuggyCoUk

2
To jest miłe. I szczególnie dobrze jest zauważyć, że ICloneable jest zawodny, bo och, tak jest zawsze.
— Marcus Griep

1
Dziękujemy za podkreślenie problemów z głębokim klonowaniem w języku C #. Szkoda, bo głębokie kopiowanie jest podstawową operacją .
— Dimitri C.

316

Możesz użyć Array.Copy(...)do skopiowania do nowej tablicy po jej utworzeniu, ale nie sądzę, że istnieje metoda, która tworzy nową tablicę i kopiuje zakres elementów.

Jeśli używasz .NET 3.5 Państwo mogli używać LINQ:

var newArray = array.Skip(3).Take(5).ToArray();

ale będzie to nieco mniej wydajne.

Zobacz odpowiedź na podobne pytanie, aby uzyskać informacje na temat bardziej szczegółowych sytuacji.


+1 Podoba mi się również ta odmiana. Jon, czy możesz wyjaśnić, dlaczego uważa się to za mniej wydajne?
— Ian Roke

@Jon: Aby pasować do pytania, czy nie brzmiałoby to „Take (5)”? @Ian: Podejście Array.Copy nie wymaga wyliczenia i najprawdopodobniej będzie zwykłą memcopy ...
— Marc Gravell

@Marc: Tak, rzeczywiście. Zbyt wiele pytań przeczesuje :)
— Jon Skeet

11
@Ian: Metoda LINQ wprowadza dwa poziomy pośredni (iteratory), musi wyraźnie pomijać elementy i nie wie, jak duża będzie ostateczna tablica. Zastanów się nad drugą połową tablicy złożonej z dwóch milionów elementów: proste podejście „stwórz tablicę docelową, skopiuj” po prostu skopiuje wymagany blok bez dotykania innych elementów i za jednym razem. Metoda LINQ będzie przechodzić przez tablicę, aż osiągnie punkt początkowy, a następnie zacznie przyjmować wartości, budować bufor (zwiększając rozmiar bufora i okresowo kopiując). O wiele mniej wydajny.
— Jon Skeet

jeśli 5 to EndIndexm, to poprawnym pytaniem jest array.Skip (3) .Take (5-3 + 1) .ToArray (); to znaczy. array.Skip (StartIndex) .Take (EndIndex-StartIndex + 1) .ToArray ();
— Klaus78,

73

Czy zastanawiałeś się nad użyciem ArraySegment?

http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx


1
Prawdopodobnie robi to, co chcesz, ale nie obsługuje domyślnej składni tablicy, ani nie obsługuje IEnumerable, więc nie jest szczególnie czysty.
— Alex Black,

5
To wymaga więcej uznania. Według mnie exp kopiowanie ArraySegment jest również nieco szybsze (w końcu używam tablic do
— rzeczy

5
@AlexBlack Wygląda jak na .NET 4.5 , implementuje IEnumerable<T>i wiele innych przydatnych interfejsów.
— pswg

1
Jak użyłbyś ArraySegmentodpowiedzi na pierwotne pytanie?
— Craig McQueen

2
@CraigMcQueen - Wypróbuj następujące podejście jednoliniowe:IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
— skia.heliou

36

Widzę, że chcesz wykonać Klonowanie, a nie tylko kopiowanie referencji. W takim przypadku możesz użyć .Selectdo rzutowania członków tablicy na ich klony. Na przykład, jeśli Twoje elementy zostały zaimplementowane, IClonablemożesz zrobić coś takiego:

var newArray = array.Skip(3).Take(5).Select(eachElement => eachElement.Clone()).ToArray();

Uwaga: To rozwiązanie wymaga .NET Framework 3.5.


To jest bardziej eleganckie.
— smwikipedia

Właśnie tego szukałem. Działa to dla każdego IEnumerable. Mogę dostać IEnumerable, IList, IArrayitp ... z minimalnym zamieszanie, inline, jeśli muszę. Jeśli nie potrzebuję głębokiej kopii, po prostu usuwam Select. Upuszczenie Skiplub Takepozwala mi kontrolować zasięg. Alternatywnie, mogę to pomieszać z SkipWhilei / lub TakeWhile.
— Mike

33

Poniższy kod robi to w jednym wierszu:

// Source array
string[] Source = new string[] { "A", "B", "C", "D" };
// Extracting a slice into another array
string[] Slice = new List<string>(Source).GetRange(2, 2).ToArray();

Podpisz linię i nie musisz dodawać Linq. To mój ulubiony sposób.
— Dimitris,

Nadal nie klonuje źródła ... ale i tak jest to dobre podejście
— IG Pascual

1
Powinien sklonować źródło, ponieważ ToArray: (1) tworzy nową tablicę i (2) wykonuje Array.Copy. Na koniec Source i Slice to dwa osobne obiekty. Takie podejście jest poprawne, jednak ja wolę Array.Copy: referencesource.microsoft.com/#mscorlib/system/collections/...
— Krauss

13

W C # 8 wprowadzili nowy Rangei Indextyp

int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Index i1 = 3;  // number 3 from beginning
Index i2 = ^4; // number 4 from end
var slice = a[i1..i2]; // { 3, 4, 5 }

12
string[] arr = { "Parrot" , "Snake" ,"Rabbit" , "Dog" , "cat" };

arr = arr.ToList().GetRange(0, arr.Length -1).ToArray();

8

Opierając się na odpowiedzi Marca, ale dodając pożądane zachowanie klonowania

public static T[] CloneSubArray<T>(this T[] data, int index, int length)
    where T : ICloneable
{
    T[] result = new T[length];
    for (int i = 0; i < length; i++)
    { 
        var original = data[index + i];
        if (original != null)
            result[i] = (T)original.Clone();            
    return result;
}

A jeśli implementacja ICloneable jest zbyt ciężka, to refleksyjna przy użyciu biblioteki Håvarda Strandena do kopiowania, aby wykonać wymagane ciężkie podnoszenie.

using OX.Copyable;

public static T[] DeepCopySubArray<T>(
    this T[] data, int index, int length)
{
    T[] result = new T[length];
    for (int i = 0; i < length; i++)
    { 
        var original = data[index + i];
        if (original != null)
            result[i] = (T)original.Copy();            
    return result;
}

Należy pamiętać, że implementacja OX.Copyable działa z dowolnym z:

Jednak aby kopia automatyczna działała, musi na przykład znajdować się jedno z poniższych stwierdzeń:

  • Jego typ musi mieć konstruktor bez parametrów lub
  • Musi to być kopia, lub
  • Musi mieć zarejestrowanego IInstanceProvider dla swojego typu.

Powinno to obejmować prawie każdą sytuację. Jeśli klonujesz obiekty, w których wykres podrzędny zawiera takie elementy, jak połączenia db lub uchwyty plików / strumieni, oczywiście masz problemy, ale jest to prawdą w przypadku każdej uogólnionej głębokiej kopii.

Jeśli zamiast tego chcesz zastosować inne podejście do głębokiego kopiowania, w tym artykule wymieniono kilka innych, więc sugeruję, aby nie próbować pisać własnego.


Pierwsze jest prawdopodobnie pożądanym rozwiązaniem, ponieważ prosi o klonowanie. Zauważ, że dzięki metodzie Copy prawdopodobnie nie musisz nawet sprawdzać, czy nie ma wartości null, ponieważ jest to metoda rozszerzenia, jeśli sama metoda już to robi. Warte spróbowania.
— Dykam

Tak, zauważyłem zerowy czek, ale nie chciałem mylić OP na wypadek, gdyby nie odczytał źródła.
— ShuggyCoUk

2
Tylko sidenote: Najnowsza wersja Copyable na GitHub nie wymaga, aby obiekty miały konstruktora bez parametrów. :) Zobacz github.com/havard/copyable
— Håvard S

8

Możesz to zrobić dość łatwo;

    object[] foo = new object[10];
    object[] bar = new object[7];   
    Array.Copy(foo, 3, bar, 0, 7);  

Nie, pasek nadal będzie pusty. Array.Copy nie tworzy magicznie nowej tablicy, zwłaszcza że bar nie jest przekazywany z ref lub out.
— Zr40

2
och, hej, masz rację, zrobiłem to w pośpiechu, ale hej, być może, kiedy piszesz krytykę, powinieneś skorygować, konstruktywna krytyka jest o wiele bardziej przydatna dla wszystkich. więc przed tym array.copy wykonujesz „bar = nowy obiekt [7];”
— RandomNickName42

4

Myślę, że kod, którego szukasz to:

Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)


Myślę, że poznałem tu dobrego przyjaciela .... taka sama odpowiedź jak ty;) i dostałem dużo głosów! hah !! W każdym razie dobre czasy dobre czasy.
— RandomNickName42

3

Alternatywnie do kopiowania danych możesz utworzyć opakowanie, które daje dostęp do części oryginalnej tablicy, tak jakby była kopią części tablicy. Zaletą jest to, że nie dostajesz kolejnej kopii danych w pamięci, a wadą jest niewielki narzut podczas uzyskiwania dostępu do danych.

public class SubArray<T> : IEnumerable<T> {

   private T[] _original;
   private int _start;

   public SubArray(T[] original, int start, int len) {
      _original = original;
      _start = start;
      Length = len;
   }

   public T this[int index] {
      get {
         if (index < 0 || index >= Length) throw new IndexOutOfRangeException();
         return _original[_start + index];
      }
   }

   public int Length { get; private set; }

   public IEnumerator<T> GetEnumerator() {
      for (int i = 0; i < Length; i++) {
        yield return _original[_start + i];
      }
   }

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

}

Stosowanie:

int[] original = { 1, 2, 3, 4, 5 };
SubArray<int> copy = new SubArray<int>(original, 2, 2);

Console.WriteLine(copy.Length); // shows: 2
Console.WriteLine(copy[0]); // shows: 3
foreach (int i in copy) Console.WriteLine(i); // shows 3 and 4

@Robert: Nie, nie jest. Spróbuj zamiast tego użyć ArraySegment, a zobaczysz, że nie możesz uzyskać dostępu do elementów według indeksu, ani iterować elementów.
— Guffa

2

Array.ConstrainedCopy będzie działać.

public static void ConstrainedCopy (
    Array sourceArray,
    int sourceIndex,
    Array destinationArray,
    int destinationIndex,
    int length
)

2
To tylko kopiuje dane; nie utworzy nowej tablicy itp .; a jeśli tablica jest nowa, możemy użyć Array.Copy, która jest bardziej wydajna (nie ma potrzeby dodatkowych kontroli / wycofywania).
— Marc Gravell

Zgadza się, ale utworzenie nowej macierzy to tylko jeden wiersz kodu i nie jest wymagana żadna nowa metoda. Zgadzam się, że Array.Copy również będzie działać.
— crauscher

1

Nie ma jednej metody, która spełni Twoje oczekiwania. Musisz udostępnić metodę klonowania dla klasy w tablicy. Następnie, jeśli LINQ jest opcją:

Foo[] newArray = oldArray.Skip(3).Take(5).Select(item => item.Clone()).ToArray();

class Foo
{
    public Foo Clone()
    {
        return (Foo)MemberwiseClone();
    }
}

1

Co powiesz na użycie Array.ConstrainedCopy :

int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8};
int[] ArrayTwo = new int[5];
Array.ConstrainedCopy(ArrayOne, 3, ArrayTwo, 0, 7-3);

Poniżej znajduje się mój oryginalny post. To nie zadziała

Możesz użyć Array.CopyTo :

int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8};
int[] ArrayTwo = new int[5];
ArrayOne.CopyTo(ArrayTwo,3); //starts copy at index=3 until it reaches end of
                             //either array

1

Co powiesz na to:

public T[] CloneCopy(T[] array, int startIndex, int endIndex) where T : ICloneable
{
    T[] retArray = new T[endIndex - startIndex];
    for (int i = startIndex; i < endIndex; i++)
    {
        array[i - startIndex] = array[i].Clone();
    }
    return retArray;

}

Następnie musisz zaimplementować interfejs ICloneable we wszystkich klasach, na których musisz go używać, ale to powinno wystarczyć.


1

Nie jestem pewien, jak głęboko jest naprawdę, ale:

MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()

Jest to trochę narzut, ale może wyeliminować niepotrzebną metodę.


1

C # 8 zapewnia funkcję o nazwie Range, aby uzyskać subarry od początku do końca indeksu. możesz użyć tego w ten sposób.

Index i1 = 3; // number 3 from beginning  
Index i2 = ^4; // number 4 from end  
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
var slice = a[i1..i2]; // { 3, 4, 5 }

To jakieś szalone pythonowe gówno. Kocham to.
— Ch3shire

Tak, to naprawdę fajna funkcja
— vivek nuna

0

Jeśli chodzi o klonowanie, nie sądzę, że serializacja wywołuje twoich konstruktorów. Może to zepsuć niezmienniki klasy, jeśli robisz ciekawe rzeczy w ctor's.

Wydaje się, że bezpieczniejszym rozwiązaniem są wirtualne metody klonowania wywołujące konstruktory kopii.

protected MyDerivedClass(MyDerivedClass myClass) 
{
  ...
}

public override MyBaseClass Clone()
{
  return new MyDerivedClass(this);
}

To, czy serializacja wywołuje konstruktorów, zależy od konkretnego serializatora. Niektórzy tak robią, inni nie. Ale te, które zwykle nie oferują obsługi oddzwaniania, aby umożliwić wykonanie wymaganych poprawek.
— Marc Gravell

Podkreśla to kolejny punkt tarcia serializacji: Musisz podać domyślne konstruktory.
— Hans Malherbe

0

Klonowanie elementów w tablicy nie jest czymś, co można zrobić w uniwersalny sposób. Czy chcesz głębokiego klonowania czy zwykłej kopii wszystkich członków?

Przejdźmy do podejścia „najlepszego wysiłku”: klonowania obiektów za pomocą interfejsu ICloneable lub serializacji binarnej:

public static class ArrayExtensions
{
  public static T[] SubArray<T>(this T[] array, int index, int length)
  {
    T[] result = new T[length];

    for (int i=index;i<length+index && i<array.Length;i++)
    {
       if (array[i] is ICloneable)
          result[i-index] = (T) ((ICloneable)array[i]).Clone();
       else
          result[i-index] = (T) CloneObject(array[i]);
    }

    return result;
  }

  private static object CloneObject(object obj)
  {
    BinaryFormatter formatter = new BinaryFormatter();

    using (MemoryStream stream = new MemoryStream())
    {
      formatter.Serialize(stream, obj);

      stream.Seek(0,SeekOrigin.Begin);

      return formatter.Deserialize(stream);
    }
  }
}

To nie jest idealne rozwiązanie, ponieważ po prostu nie ma takiego, który działałby dla dowolnego typu obiektu.


Czy nie powinno to być coś w rodzaju wyniku [i-index] = (T) ...?
— Donald Byrd

tak :) I nie tylko. Granica pętli jest nieprawidłowa. Naprawię to. Dzięki!
— Philippe Leybaert

0

Możesz wziąć udział w zajęciach wykonanych przez Microsoft:

internal class Set<TElement>
{
    private int[] _buckets;
    private Slot[] _slots;
    private int _count;
    private int _freeList;
    private readonly IEqualityComparer<TElement> _comparer;

    public Set()
        : this(null)
    {
    }

    public Set(IEqualityComparer<TElement> comparer)
    {
        if (comparer == null)
            comparer = EqualityComparer<TElement>.Default;
        _comparer = comparer;
        _buckets = new int[7];
        _slots = new Slot[7];
        _freeList = -1;
    }

    public bool Add(TElement value)
    {
        return !Find(value, true);
    }

    public bool Contains(TElement value)
    {
        return Find(value, false);
    }

    public bool Remove(TElement value)
    {
        var hashCode = InternalGetHashCode(value);
        var index1 = hashCode % _buckets.Length;
        var index2 = -1;
        for (var index3 = _buckets[index1] - 1; index3 >= 0; index3 = _slots[index3].Next)
        {
            if (_slots[index3].HashCode == hashCode && _comparer.Equals(_slots[index3].Value, value))
            {
                if (index2 < 0)
                    _buckets[index1] = _slots[index3].Next + 1;
                else
                    _slots[index2].Next = _slots[index3].Next;
                _slots[index3].HashCode = -1;
                _slots[index3].Value = default(TElement);
                _slots[index3].Next = _freeList;
                _freeList = index3;
                return true;
            }
            index2 = index3;
        }
        return false;
    }

    private bool Find(TElement value, bool add)
    {
        var hashCode = InternalGetHashCode(value);
        for (var index = _buckets[hashCode % _buckets.Length] - 1; index >= 0; index = _slots[index].Next)
        {
            if (_slots[index].HashCode == hashCode && _comparer.Equals(_slots[index].Value, value))
                return true;
        }
        if (add)
        {
            int index1;
            if (_freeList >= 0)
            {
                index1 = _freeList;
                _freeList = _slots[index1].Next;
            }
            else
            {
                if (_count == _slots.Length)
                    Resize();
                index1 = _count;
                ++_count;
            }
            int index2 = hashCode % _buckets.Length;
            _slots[index1].HashCode = hashCode;
            _slots[index1].Value = value;
            _slots[index1].Next = _buckets[index2] - 1;
            _buckets[index2] = index1 + 1;
        }
        return false;
    }

    private void Resize()
    {
        var length = checked(_count * 2 + 1);
        var numArray = new int[length];
        var slotArray = new Slot[length];
        Array.Copy(_slots, 0, slotArray, 0, _count);
        for (var index1 = 0; index1 < _count; ++index1)
        {
            int index2 = slotArray[index1].HashCode % length;
            slotArray[index1].Next = numArray[index2] - 1;
            numArray[index2] = index1 + 1;
        }
        _buckets = numArray;
        _slots = slotArray;
    }

    internal int InternalGetHashCode(TElement value)
    {
        if (value != null)
            return _comparer.GetHashCode(value) & int.MaxValue;
        return 0;
    }

    internal struct Slot
    {
        internal int HashCode;
        internal TElement Value;
        internal int Next;
    }
}

i wtedy

public static T[] GetSub<T>(this T[] first, T[] second)
    {
        var items = IntersectIteratorWithIndex(first, second);
        if (!items.Any()) return new T[] { };


        var index = items.First().Item2;
        var length = first.Count() - index;
        var subArray = new T[length];
        Array.Copy(first, index, subArray, 0, length);
        return subArray;
    }

    private static IEnumerable<Tuple<T, Int32>> IntersectIteratorWithIndex<T>(IEnumerable<T> first, IEnumerable<T> second)
    {
        var firstList = first.ToList();
        var set = new Set<T>();
        foreach (var i in second)
            set.Add(i);
        foreach (var i in firstList)
        {
            if (set.Remove(i))
                yield return new Tuple<T, Int32>(i, firstList.IndexOf(i));
        }
    }

0

Przekonałem się, że jest to optymalny sposób:

private void GetSubArrayThroughArraySegment() {
  int[] array = { 10, 20, 30 };
  ArraySegment<int> segment = new ArraySegment<int>(array,  1, 2);
  Console.WriteLine("-- Array --");
  int[] original = segment.Array;
  foreach (int value in original)
  {
    Console.WriteLine(value);
  }
  Console.WriteLine("-- Offset --");
  Console.WriteLine(segment.Offset);
  Console.WriteLine("-- Count --");
  Console.WriteLine(segment.Count);

  Console.WriteLine("-- Range --");
  for (int i = segment.Offset; i <= segment.Count; i++)
  {
    Console.WriteLine(segment.Array[i]);
  }
}

Mam nadzieję, że to pomoże!


0

użyj metody rozszerzenia:

public static T[] Slice<T>(this T[] source, int start, int end)
    {
        // Handles negative ends.
        if (end < 0)
        {
            end = source.Length + end;
        }
        int len = end - start;

        // Return new array.
        T[] res = new T[len];
        for (int i = 0; i < len; i++)
        {
            res[i] = source[i + start];
        }
        return res;
    }

i możesz z niego korzystać

var NewArray = OldArray.Slice(3,7);

0

Kod z System.Private.CoreLib.dll:

public static T[] GetSubArray<T>(T[] array, Range range)
{
    if (array == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
    }
    (int Offset, int Length) offsetAndLength = range.GetOffsetAndLength(array.Length);
    int item = offsetAndLength.Offset;
    int item2 = offsetAndLength.Length;
    if (default(T) != null || typeof(T[]) == array.GetType())
    {
        if (item2 == 0)
        {
            return Array.Empty<T>();
        }
        T[] array2 = new T[item2];
        Buffer.Memmove(ref Unsafe.As<byte, T>(ref array2.GetRawSzArrayData()), ref Unsafe.Add(ref Unsafe.As<byte, T>(ref array.GetRawSzArrayData()), item), (uint)item2);
        return array2;
    }
    T[] array3 = (T[])Array.CreateInstance(array.GetType().GetElementType(), item2);
    Array.Copy(array, item, array3, 0, item2);
    return array3;
}



0

Nie spełnia twoich wymagań dotyczących klonowania, ale wydaje się łatwiejsze niż wiele odpowiedzi do zrobienia:

Array NewArray = new ArraySegment(oldArray,BeginIndex , int Count).ToArray();

-1
public   static   T[]   SubArray<T>(T[] data, int index, int length)
        {
            List<T> retVal = new List<T>();
            if (data == null || data.Length == 0)
                return retVal.ToArray();
            bool startRead = false;
            int count = 0;
            for (int i = 0; i < data.Length; i++)
            {
                if (i == index && !startRead)
                    startRead = true;
                if (startRead)
                {

                    retVal.Add(data[i]);
                    count++;

                    if (count == length)
                        break;
                }
            }
            return retVal.ToArray();
        }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.