C# - 返回通用数组类型

时间:2014-04-04 10:59:16

标签: c# arrays generics types generic-programming

如果我有一个简单的Utility函数将数组复制到一个新数组:

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的声明以使其动态接受并返回任何类型的数组?我相信Generics就是这样(虽然我不太熟悉这个)所以我试过了:

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

但是编译器不会将T识别为类型。

3 个答案:

答案 0 :(得分:7)

要使其通用,请使用以下代码:

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

答案 1 :(得分:1)

试试这个:

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

答案 2 :(得分:1)

我认为您不需要编写自己的函数,.NET Framework已经内置了所有内容。请看这个示例:

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指定目标数组中开始插入的索引,最后{{1}指定要复制的元素数量。


注意还有一个更简单的版本srcElements方法。它的工作原理如下:

.CopyTo

它返回:

  

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

第二个参数指定数据插入位置的索引(就像上一个例子中的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)); } 一样),这就是前3个元素为0的原因。

您也可以将它与其他数据类型一起使用,例如:

tgtStart

以同样的方式运作。