簡體   English   中英

C# - 返回泛型數組類型

[英]C# - Return generic array type

如果我有一個簡單的實用函數,可以將數組復制到新數組:

public static object[] CopyTo(object[] original, int startIndex, int endIndex)
{
    List<object> copied - new List<object>();
    for (int i = startIndex; i <= endIndex; i++) 
    {
        copied.Add(original[i]);
    }
    return copied.ToArray();
}

然后我希望能夠像這樣調用它:

int[] newThing = CopyTo(new int[] { 10, 9, 8, 7, 6 }, 2, 4);

編譯器錯誤說cannot convert from int[] to object[] 這是意料之中的,因為我的CopyTo函數特別需要一個對象數組,而不是一個整數數組。

如何更改 CopyTo 的聲明以使其動態接受並返回任何類型的數組? 我相信泛型是一種方式(盡管我對此不太熟悉)所以我嘗試了:

public static T[] CopyTo(T[] original, int startIndex......)

但編譯器不會將 T 識別為類型。

要使其通用,請使用以下代碼:

public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
    List<T> copied = new List<T>();
    for (int i = startIndex; i <= endIndex; i++) 
    {
        copied.Add(original[i]);
    }
    return copied.ToArray();
}

編輯:

順便提一下,您也可以在不創建List<T>並將列表作為數組返回的情況下執行此操作。 只需創建一個數組(長度等於所需元素的數量)並填充它:

public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
    int count = (endIndex - startIndex) + 1;
    int index = 0;
    T[] copied = new T[count];

    for (int i = startIndex; i <= endIndex; i++) 
        copied[index++] = original[i];

    return copied;
}

你也可以為它創建一個擴展方法:

public static class Extensions
{
    public static T[] CopyTo<T>(this T[] source, int start, int end)
    {
        int count = (end - start) + 1;
        int index = 0;
        T[] copied = new T[count];

        for (int i = start; i <= end; i++) 
            copied[index++] = source[i];

        return copied;
    }
}

現在你可以這樣稱呼它:

var original = new int[] { 10, 9, 8, 7, 6 };
var newThing = original.CopyTo(0, 2);

或者對於字符串數組:

var strOrig = "one.two.three.four.five.six.seven".Split('.');
var strNew = strOrig.CopyTo(2, 5);

嘗試這個:

public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
    List<T> copied = new List<T>();
    for (int i = startIndex; i < endIndex; i++) 
    {
        copied.Add(original[i]);
    }
    return copied.ToArray();
}

您不需要編寫自己的函數,.NET Framework 已經內置了所有功能。您有兩個選擇:

  • Array.Copy(sourceArray, srcStartIndex, targetArray, tgtStartIndex, srcNumberOfElements);
  • sourceArray.CopyTo(targetArray, tgtStartIndex);

我先用一些例子來解釋它們,最后我會把它組合成一個函數

public static T[] CopyFromArray<T>(this T[] sourceArray, int startIndex, int endIndex)

正如您在問題中所要求的那樣(CopyTo 已被 .NET 保留,因此我將其重命名為 CopyFromArray)。

注意sourceArraytargetArray是任何類型的數組; srcStartIndex是開始指數sourceArray從,復制tgtStartIndex是開始指數targetArray復制到和srcNumberOfElements是你想從源數組復制元素的數量。

目標數組必須足夠大以將所有元素復制到其中,否則會出錯。 源數組的元素被直接復制到目標數組中(“原位”),這就是函數沒有返回任何數據的原因(返回類型為void )。

看這個例子:

void Main()
{
    var target = new int[20];
    var srcStart=1; var tgtStart=3; var srcElements=3;
    Array.Copy((new int[] { 1,2,3,4,5,6,7,8,9 }), srcStart, 
        target, tgtStart, srcElements);
    Console.WriteLine(string.Join(",", target));
}

它工作正常並返回:

0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0

請注意, srcStart指定源數組中的索引,從該索引開始復制,而tgtStart指定目標數組中開始插入的索引,最后, srcElements指定要復制的元素數量。


請注意,還有一個更簡單的版本,即.CopyTo方法。 它的工作原理如下:

void Main()
{
    var target = new int[20]; var tgtStart = 3;
    (new int[] { 1,2,3,4,5,6,7,8,9 }).CopyTo(target, tgtStart);
    Console.WriteLine(string.Join(",", target));
}

它返回:

0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0

第二個參數指定數據插入位置的索引(就像前面例子中的tgtStart一樣),這就是前 3 個元素為 0 的原因。

您也可以將它與其他數據類型一起使用,例如:

    var target = new string[20];
    (new string[] { "abc", "def", "ghi" }).CopyTo(target, 3);

以同樣的方式工作。


談到您的問題,您可以使用我迄今為止提供給您的信息來組合您自己的通用擴展方法,如下所示:

void Main()
{
    int[] newThing1 = (new int[] { 10, 9, 8, 7, 6 }).CopyFromArray(2, 4);
    newThing1.Dump();

    string[] newThing2 = (new string[] { "A",  "B",  "C",  "D"}).CopyFromArray(1, 3);
    newThing2.Dump();
}

public static class Extensions
{
    public static T[] CopyFromArray<T>(this T[] sourceArray, int startIndex, int endIndex)
    {
        int numberOfElements = endIndex - startIndex + 1;
        var targetArray = new T[numberOfElements];
        Array.Copy(sourceArray, startIndex, targetArray, 0, numberOfElements);
        return targetArray;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM