我的程序大量使用Reverse,例如Array.Reverse(myArray,3,5)
我希望我的程序可以接受array和List作为输入,所以我选择IList
但是,我找不到与Reverse相同的IList方法。
有一个名为Reverse的扩展方法,但是它会生成IEnumerable流,但不会就地重新排列。(我认为这需要更多的复制时间)
我想过使用cast,但又担心cast的效率会很低。
那么,我该怎么做呢?
最坏的情况是,我做了2个程序,一个取数组,另一个取列表,然后重载?
发布于 2012-07-02 23:11:50
OOP-way -制作一个包装器,重载它十几次:
public void Reverse(Array arr, int index, int count)
{
Array.Reverse(arr, index, count);
}
public void Reverse<T>(List<T> lst, int index, int count)
{
lst.Reverse(index, count);
}每次需要以这种方式反转另一个类似集合的类时,都要添加一个重载。这种方法依赖于系统内部,非常有效和健壮,但如果您愿意反转许多类型的对象,则可能会很冗长。
I-can-do-it-myself better-way:
static class Extensions
{
public static void Reverse(this IList target, int index, int count)
{
int right = index + count - 1;
int left = index;
while (right>left)
{
var tmp = target[left];
target[left] = target[right];
target[right] = tmp;
right--;
left++;
}
}
}只需添加范围检查/前置条件/不变量/等。此外,它对于列表可能效率不高,因为它需要随机访问列表的内容,但我认为你不能使用“常规武器”来解决它(即不使用反射和直接内存操作)。
所以,我的建议是-重载是可行的。
发布于 2012-07-03 00:10:15
Linq Reverse()扩展方法缺少一个明显的优化,它总是创建一个临时数组来存储元素来反转它们。在列表或数组上使用它的开销太大了。
如果您想要一个就地反转,那么您可以编写一个扩展方法来选择正确的Reverse()方法:
public static class MyExtensions {
public static void Reverse<T>(this IList<T> source) {
if (source is List<T>) {
((List<T>)source).Reverse();
}
else if (source is T[]) {
Array.Reverse((T[])source);
}
else throw new ArgumentException();
}
}您可以用同样的方法修复Linq反向方法:
public static class MyExtensions {
public static IEnumerable<T> Reverse<T>(this IEnumerable<T> source) {
if (source is IList<T>) {
var list = (IList<T>)source;
for (int ix = list.Count - 1; ix >= 0; --ix) {
yield return list[ix];
}
}
else {
foreach (var item in Enumerable.Reverse(source)) {
yield return item;
}
}
}
}发布于 2012-07-02 21:59:22
Reverse()将根据列表直接生成一个IEnumerable;不涉及复制。试一试,如果你只是迭代,它可能会更有效率。
https://stackoverflow.com/questions/11295184
复制相似问题