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(在上面的例子中没有这样做码)。
做没有泛型然后用T.
这里是一个非常简单的实现:
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);
为什么你明确指定泛型类型参数? – 2009-08-19 15:29:37
数组是这样2004年
public IEnumerable<string> ArrayItms(IEnumerable<string> a, IEnumerable<string> b)
{
return a.Concat(b);
}
你可以通过你的阵列直接这个功能,因为数组实现IEnumerable。如果您确实需要数组结果,请在调用该函数后调用.ToArray()
。或者,因为它只是一个单线程,完全跳过该函数,只需在第一个数组上调用.Concat()
即可。
请注意,这是很容易转换为一个通用的函数,将与任何类型的工作。但是到目前为止,你只说过你关心字符串。
最佳解决方案。 +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进行基准测试,或者一个强类型版本可以定制。
现在编辑我的帖子回答问题,请删除downvote。 – 2009-08-19 15:34:24
没有看到您的答案。我删除了最小。我只是补充一下: 它可以工作,因为数组是C#版本1以后的运行时的协变量。编译时安全性由通用约束保证。 – thinkbeforecoding 2009-08-19 15:49:18
只是我还是会失败。 T1和T2没有定义,不能转换为T – LorenVS 2009-08-19 15:26:43
好!有很多很好的新方法支持LINQ。 – akmad 2009-08-19 15:26:46
@Loren:我现在修好了。使用不同的参数类型可能实际上是有意义的,但是(如果它们以某种方式可以相互转换)。我会暂时放弃它,看看OP有什么话要说。 – 2009-08-19 15:27:46