Varolan bir diziden alt dizi alma


335

10 elemanlık bir dizi X var. X dizin 3'te başlayan ve dizin 7 biten tüm öğeleri içeren yeni bir dizi oluşturmak istiyorum. Eminim kolayca benim için yapacak bir döngü yazabilirsiniz ama kodumu olabildiğince temiz tutmak istiyorum . C # benim için yapabileceğiniz bir yöntem var mı?

Gibi bir şey (sözde kod):

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

Array.Copyihtiyaçlarımı karşılamıyor . Klon olmak için yeni dizideki öğeleri gerekir. Array.copysadece bir C-Style memcpyeşdeğeri, aradığım şey bu değil.



7
@Kirtan - bu "dup" özellikle IEnumerable <T> istiyor - ki bu farklı ve farklı en uygun çözümlere sahip; IMO
Marc Gravell

Yani, yeni dizi ve çağrı .Copy () bildirmek için gereken iki satır "temiz kod" değil mi?
Ed S.

2
@Ed Swangren - zincirleme bir ifadenin ortasında yapmanıza gerek yok, hayır ;-p
Marc Gravell

2
ShaggyUk'un cevabı muhtemelen doğru: stackoverflow.com/questions/943635/…
Dykam

Yanıtlar:


469

Bir uzantı yöntemi olarak ekleyebilirsiniz:

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}
}

Güncelleme yeniden klonlama (orijinal soruda belirgin değildi). Eğer varsa gerçekten derin bir klon istiyorum; gibi bir şey:

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);
    }
}

Bu, nesnelerin serileştirilebilir ( [Serializable]veya ISerializable) olmasını gerektirir . Uygun şekilde diğer herhangi bir serileştiricinin yerine geçebilirsiniz - XmlSerializer,, protobuf DataContractSerializer-net, vb.

Derin klonun serileştirme olmadan zor olduğunu unutmayın; özellikle, ICloneableçoğu durumda güvenmek zordur.


1
(açıkçası bir uzunluk yerine bir uç endeksi kullanmak basit bir değişikliktir, çünkü ben "olduğu gibi" yayınladım çünkü bu daha "tipik" bir kullanımdır)
Marc Gravell

1
Sonra ... zor; bunu yapmaz .... muhtemelen benzer bir şey elde etmek için serileştirme kullanmanız gerekir
Marc Gravell

1
bazı alternatifler için cevabımı ve birkaç uygulamanın bağlantısını görebilirsiniz. bir alt diziye yapmakla ilgili kısım gerçekten önemsizdir, gerçekten istediğiniz şey klonlama bitidir ve bu tamamen 'doğru' davranışın ne olması gerektiğine dair beklentilerinize bağlı olan karmaşık ve biraz açık bir sorudur .
ShuggyCoUk

2
Bu güzel. Ve özellikle ICloneable'un güvenilmez olduğuna dikkat etmek iyi, çünkü oh, hiç öyle değil.
Marcus Griep

1
C # 'da derin klonlama ile ilgili sorunların altını çizdiğiniz için teşekkür ederiz. Derin kopyalama temel bir işlem olduğu için gerçekten utanç verici .
Dimitri C.

317

Array.Copy(...)Oluşturduktan sonra yeni diziye kopyalamak için kullanabilirsiniz , ancak yeni diziyi oluşturan ve bir dizi öğeyi kopyalayan bir yöntem olduğunu düşünmüyorum .

Eğer .NET 3.5 kullanıyorsanız, olabilir LINQ kullanmak:

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

ancak bu biraz daha az verimli olacaktır.

Daha spesifik durumlar için seçenekler için benzer bir soruya verilen bu cevaba bakınız .


+1 Ben de bu varyasyonu seviyorum. Jon, bunun neden daha az verimli göründüğünü genişletebilir misin?
Ian Roke

@Jon: Soruyu eşleştirmek için bu "Al (5)" değil mi? @Ian: Array.Copy yaklaşımı bir numaralandırıcı içermiyor ve büyük olasılıkla düz bir anı olacak ...
Marc Gravell

@Marc: Evet, gerçekten. Çok fazla soru gözden geçirme :)
Jon Skeet

11
@Ian: LINQ yaklaşımı iki düzeyde dolaylılık (yineleyiciler) sunar, öğeleri açıkça atlamak zorundadır ve son dizinin önceden ne kadar büyük olacağını bilmez. İki milyon elementlik bir dizinin ikinci yarısını almayı düşünün: basit bir "hedef dizi oluştur, kopyala" yaklaşımı, gerekli bloğu diğer öğelere dokunmadan ve bir seferde kopyalar. LINQ yaklaşımı, başlangıç ​​noktasına ulaşana kadar dizi boyunca ilerleyecek, daha sonra değerler almaya, bir tampon oluşturmaya (tampon boyutunu artırarak ve periyodik olarak kopyalama) başlayacaktır. Çok daha az verimli.
Jon Skeet

5 EndIndexm ise, doğru soru dizidir.Skip (3). (5-3 + 1) .ToArray (); yani. array.Skip (startIndex'ten) sökünüz (endIndex-startIndex'ten + 1) .ToArray ();
Klaus78

73

Kullanmayı düşündünüz mü ArraySegment?

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


1
Muhtemelen istediğinizi yapar, ancak varsayılan dizi sözdizimini desteklemez veya IEnumerable'ı desteklemez, bu yüzden özellikle temiz değildir.
Alex Black

5
Bunun daha fazla oy alması gerekiyor. Kendi exp, ArraySegment kopyalama da biraz daha hızlı (sonuçta hız kritik
şeyler

5
@AlexBlack .NET 4.5 gibi görünüyor , uygular IEnumerable<T>ve diğer çeşitli kullanışlı arayüzler.
pswg

1
ArraySegmentOrijinal soruyu cevaplamak için nasıl kullanılır ?
Craig McQueen

2
@CraigMcQueen - Aşağıdaki tek hat yaklaşımını deneyin:IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
skia.heliou

36

Sadece referansları kopyalamakla kalmayıp Klonlama yapmak istediğinizi görüyorum. Bu durumda, .Selectdizi üyelerini klonlarına yansıtmak için kullanabilirsiniz . Örneğin, öğeleriniz uygulandığında IClonableböyle bir şey yapabilirsiniz:

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

Not: Bu çözüm için .NET Framework 3.5 gerekir.


Bu daha zarif.
smwikipedia

Tam da aradığım şey buydu. Bu herkes için geçerlidir IEnumerable. Bir alabilirsiniz IEnumerable, IList, IArrayben gerek inline varsa, en az yaygara ile ... vb. Derin kopyaya ihtiyacım yoksa, yalnızca Select. Düşüyor Skipveya Takemenzili kontrol etmeme izin veriyor. Alternatif olarak SkipWhileve / veya ile karıştırabilirim TakeWhile.
Mike

33

Aşağıdaki kod tek bir satırda bunu yapar:

// 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();

Singe hattı ve Linq eklemeye gerek yok. Bu benim tercih ettiğim yol.
Dimitris

Hala kaynağı klonlamıyor ... ama yine de iyi bir yaklaşım
IG Pascual

1
ToArray: (1) yeni bir dizi oluşturduğu ve (2) Array.Copy yürüttüğü için kaynağı klonlamalıdır. Sonunda Kaynak ve Dilim iki ayrı nesnedir. Yaklaşım doğru ancak Array.Copy'yi tercih ediyorum: referenceource.microsoft.com/#mscorlib/system/collections/…
Krauss

13

C # 8'de yeni bir sunduk Rangeve Indextürünü

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

Marc'ın cevabına dayanmak ama istenen klonlama davranışını eklemek

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;
}

Ve eğer ICloneable uygulamak zor bir iş gibi ise, Håvard Stranden'in Copdable kütüphanesini kullanarak ağır kaldırma yapmak için yansıtıcı bir çalışma .

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;
}

OX.Copyable uygulamasının aşağıdakilerden herhangi biriyle çalıştığını unutmayın:

Ancak otomatik kopyanın çalışması için aşağıdaki ifadelerden birinin örneğin tutulması gerekir:

  • Türü parametresiz bir kurucuya sahip olmalı veya
  • Bir Copdable olmalı veya
  • Türü için bir IInstanceProvider kayıtlı olması gerekir.

Yani bu neredeyse her durumunuzu kapsamalıdır. Alt grafiğin db bağlantıları veya dosya / akış tutamaçları gibi şeyler içerdiği nesneleri klonluyorsanız, açık bir şekilde sorunlarınız var, ancak herhangi bir genelleştirilmiş derin kopya için doğru.

Başka derin kopya yaklaşımını kullanmak istiyorsanız, bu makalede birkaç tane listelenir, bu yüzden kendi yazmaya çalışmamanızı öneririm.


Birincisi, klonlama istediği için muhtemelen istenen çözümdür. Kopyalama yöntemiyle, yöntemin zaten bu şeyi yapması durumunda, bir uzantı yöntemi olduğundan, null değerini kontrol etmeniz bile gerekmeyeceğini unutmayın. Denemeye değer.
Dykam

Evet null kontrolüne dikkat ettim ancak kaynağı okumaması durumunda OP'yi karıştırmak istemedim.
ShuggyCoUk

2
Sadece bir sidenote: GitHub'da Copyable'ın en son sürümü, nesnelerin parametresiz bir kurucuya sahip olmasını gerektirmez. :) Bakınız github.com/havard/copyable
Håvard S

8

Bunu oldukça kolay bir şekilde yapabilirsiniz;

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

Hayır, çubuk hala boş olacaktır. Array.Copy sihirli bir şekilde yeni bir dizi oluşturmaz, özellikle çubuk ref veya out ile iletilmediğinden.
Zr40

2
oh ya hey, haklısın, bunu acele bir whops yaptım, ama hey, belki de yazma eleştiriniz düzeltmeyi yapmalısınız, yapıcı eleştiri herkes için çok daha yararlıdır. yani array.copy'den önce bir "bar = yeni nesne [7];"
RandomNickName42

4

Aradığınız kod olduğunu düşünüyorum:

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


Sanırım bazı iyi arkadaşım burada yapıyorum .... sizinle aynı cevap;) ve ben aşağı bol oy! hah !! Her neyse, iyi günler iyi günler.
RandomNickName42

3

Verileri kopyalamaya alternatif olarak, orijinal dizinin bir bölümüne, dizinin bir parçasıymış gibi erişmenizi sağlayan bir sarıcı yapabilirsiniz. Avantajı, bellekteki verilerin başka bir kopyasını almamanız ve verilere erişirken dezavantaj hafif bir ek yük olmasıdır.

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();
   }

}

Kullanımı:

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: Hayır, değil. Bunun yerine bir ArraySegment kullanmaya çalışın ve öğeleri öğelere yinelemek yerine dizine erişemeyeceğinizi görüyorsunuz.
Guffa

2

Array.ConstrainedCopy çalışır.

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

2
Bu sadece verileri kopyalar; yeni dizi vb. yaratmaz; ve dizi yeni ise, daha verimli olan Array.Copy'yi kullanabiliriz (ek kontrollere / geri almalara gerek yoktur).
Marc Gravell

Bu doğru, ancak yeni bir Array oluşturmak yalnızca bir kod satırıdır ve yeni bir yönteme gerek yoktur. Array.Copy'nin de çalışacağına katılıyorum.
crauscher

1

İstediğinizi yapacak tek bir yöntem yoktur. Dizinizdeki sınıf için bir klonlama yöntemi kullanmanız gerekir. Sonra, LINQ bir seçenek ise:

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

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

1

Array.ConstrainedCopy kullanmaya ne dersiniz :

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);

Aşağıda benim orijinal yazım. Çalışmayacak

Array.CopyTo kullanabilirsiniz :

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

Buna ne dersin:

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;

}

Daha sonra bunu kullanmanız gereken tüm sınıflara ICloneable arabirimini uygulamanız gerekir, ancak bunu yapmanız gerekir.


1

Gerçekten ne kadar derin olduğundan emin değilim, ama:

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

Biraz ek yük, ancak gereksiz bir yöntemi kesebilir.


1

C # 8, başlangıçtan bitişe kadar alt diziyi almak için Aralık olarak adlandırılan bir özellik sağlamıştır. bu şekilde kullanabilirsiniz.

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 }

Bu çılgın bir pitonik s ** t. Onu seviyorum.
Ch3shire

Evet, gerçekten güzel bir özellik
vivek nuna

0

Klonlama ile ilgili olarak, serileştirmenin inşaatçılarınızı çağırdığını sanmıyorum. Eğer ctor'da ilginç şeyler yapıyorsanız bu sınıf değişmezlerini kırabilir.

Daha güvenli bahis kopya kurucuları olarak adlandırılan sanal klon yöntemleri gibi görünüyor.

protected MyDerivedClass(MyDerivedClass myClass) 
{
  ...
}

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

Serileştirmenin kurucularınızı çağırıp çağırmayacağı belirli serileştiriciye bağlıdır. Bazıları yapar, bazıları yapmaz. Ancak, gerekli düzeltmeleri yapmanıza izin vermek için genellikle geri arama desteği sunmayanlar.
Marc Gravell

Bu, başka bir sürtünme serileştirme noktasını vurgular: Varsayılan kurucuları sağlamanız gerekir.
Hans Malherbe

0

Bir dizideki öğeleri klonlamak evrensel bir şekilde yapılabilecek bir şey değildir. Derin klonlama mı yoksa tüm üyelerin basit bir kopyası mı istiyorsunuz?

"En iyi çaba" yaklaşımına geçelim: ICloneable arabirimini veya ikili serileştirmeyi kullanarak nesneleri klonlama:

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);
    }
  }
}

Bu mükemmel bir çözüm değildir, çünkü herhangi bir nesne türü için işe yarayacak hiçbir şey yoktur.


Sonuç [i-index] = (T) gibi bir şey değil miydi?
Donald Byrd

evet :) Ve sadece bu da değil. Döngü sınırı yanlış. Ben tamir edeceğim. Teşekkürler!
Philippe Leybaert

0

Microsoft tarafından yapılan dersi alabilirsiniz:

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;
    }
}

ve sonra

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

Bunu yapmanın en iyi yolu budur:

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]);
  }
}

Umarım yardımcı olur!


0

genişletme yöntemini kullanın:

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;
    }

ve kullanabilirsiniz

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

0

System.Private.CoreLib.dll kodu:

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

Klonlama gereksiniminizi karşılamıyor, ancak yapılacak birçok yanıttan daha basit görünüyor:

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();
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.