C# - Generics-串阵列处理

问题描述:

我们有两个组字符串数组,例如:C# - Generics-串阵列处理

string[] a = new string[] {"value1","value2","value3"}; 
string[] b = new string[] {"value1","value2","value3"}; 

我必须开发一种应采取这两个字符串数组的通用方法作为参数 和应返回合并一个回:

public T[] ArrayItms(T1[] a, T2[] b) 
{ 
    return T[]; 
} 

我有点困惑,在泛型中这样做。

您可以使用LINQ来做到这一点:

public T[] ArrayItms<T>(T[] a, T[] b) 
{ 
    return a.Concat(b).ToArray(); 
} 

或者,通过复制阵列做手工:

public T[] ArrayItms<T>(T[] a, T[] b) 
{ 
    T[] result = new T[a.Length + b.Length]; 
    Array.Copy(a, result, a.Length); 
    Array.Copy(b, 0, result, a.Length, b.Length); 
    return result; 
} 

在这两种情况下,谨防未初始化paremeters(在上面的例子中没有这样做码)。

+0

只是我还是会失败。 T1和T2没有定义,不能转换为T – LorenVS 2009-08-19 15:26:43

+0

好!有很多很好的新方法支持LINQ。 – akmad 2009-08-19 15:26:46

+0

@Loren:我现在修好了。使用不同的参数类型可能实际上是有意义的,但是(如果它们以某种方式可以相互转换)。我会暂时放弃它,看看OP有什么话要说。 – 2009-08-19 15:27:46

做没有泛型然后用T.

因为数组的IEnumerable替换字符串每次出现时,您可以使用此:http://msdn.microsoft.com/en-us/library/bb302894.aspx

这里是一个非常简单的实现:

public T[] Combine<T>(IEnumerable<T> a, IEnumerable<T> b) 
{ 
    List<T> result = new List<T>(a); 

    result.AddRange(b); 

    return result.ToArray(); 
} 

嗯...这似乎并没有遵循正确的泛型的规则,你的阵列参数应该具有相同的类型,像这样:

public T[] ArrayItems<T>(T[] a, T[] b) 
{ 
    return a.Concat(b).ToArray(); 
} 

或者,你可以做这样的事情:

public T[] ArrayItems<T,T1,T2>(T1[] a, T2[]b) where T1 : T where T2 : T 
{ 
    return a.Select(i => (T)i).Concat(b.Select(i=>(T)i)).ToArray(); 
} 

您可以使用LINQ来做到这一点,因此应该将它更改为

public T[] ArrayItms<T>(T[] a, T[] b) 
{ 
    return a.Concat(b).ToArray(); 
} 

注意不能将两个阵列的不同类型(T1,T2 - > T,T)的和必须使用方法名。你应该调用该方法,如:

ArrayItems<TypeName>(TypeName a, TypeName b); 
+0

为什么你明确指定泛型类型参数? – 2009-08-19 15:29:37

数组是这样2004年

public IEnumerable<string> ArrayItms(IEnumerable<string> a, IEnumerable<string> b) 
{ 
    return a.Concat(b); 
} 

你可以通过你的阵列直接这个功能,因为数组实现IEnumerable。如果您确实需要数组结果,请在调用该函数后调用.ToArray()。或者,因为它只是一个单线程,完全跳过该函数,只需在第一个数组上调用.Concat()即可。

请注意,这是很容易转换为一个通用的函数,将与任何类型的工作。但是到目前为止,你只说过你关心字符串。

+0

最佳解决方案。 +1 – 2009-08-19 15:30:08

如果两个数组都是完全相同的类型,你可以使用:

public static T[] Concatenate<T>(T[] a, T[] b) 
{ 
    if (a == null) throw new ArgumentNullException("a"); 
    if (b == null) throw new ArgumentNullException("b"); 

    T[] result = new T[a.Length + b.Length]; 
    Array.Copy(a, result, a.Length); 
    Array.Copy(b, 0, result, a.Length, b.Length); 
    return result; 
} 

否则

public static TResult[] Concatenate<TResult, T1, T2>(T1[] a, T2[] b) 
    where T1 : TResult where T2 : TResult 
{ 
    if (a == null) throw new ArgumentNullException("a"); 
    if (b == null) throw new ArgumentNullException("b"); 

    TResult[] result = new TResult[a.Length + b.Length]; 
    Array.Copy(a, result, a.Length); 
    Array.Copy(b, 0, result, a.Length, b.Length); 
    return result; 
} 

应该做的。

编辑: 也许Array.Copy()不是快,所以它可以对LINQ的CONCAT进行基准测试,或者一个强类型版本可以定制。

+0

现在编辑我的帖子回答问题,请删除downvote。 – 2009-08-19 15:34:24

+0

没有看到您的答案。我删除了最小。我只是补充一下: 它可以工作,因为数组是C#版本1以后的运行时的协变量。编译时安全性由通用约束保证。 – thinkbeforecoding 2009-08-19 15:49:18