Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用反向(数组、Int32、Int32)或列表<;T>;::IList上的反向方法(Int32,Int32)?_C# - Fatal编程技术网

C# 如何使用反向(数组、Int32、Int32)或列表<;T>;::IList上的反向方法(Int32,Int32)?

C# 如何使用反向(数组、Int32、Int32)或列表<;T>;::IList上的反向方法(Int32,Int32)?,c#,C#,我的程序大量使用Reverse,例如Array.Reverse(myArray,3,5) 我希望我的程序可以同时接受数组和列表作为输入,所以我选择IList 但是,我找不到与Reverse相同的IList方法 有一个扩展方法名为Reverse,但是它会生成IEnumerable流,但不会就地重新排列。(我认为这需要更多的复制时间) 我曾想过使用cast,但担心cast也会效率低下 那么,我该怎么办 最坏的情况是,我制作2个程序,1个takes数组,另一个takes列表,然后重载?Reverse(

我的程序大量使用
Reverse
,例如
Array.Reverse(myArray,3,5)

我希望我的程序可以同时接受
数组
列表
作为输入,所以我选择
IList

但是,我找不到与
Reverse
相同的
IList
方法

有一个扩展方法名为
Reverse
,但是它会生成
IEnumerable
流,但不会就地重新排列。(我认为这需要更多的复制时间)

我曾想过使用
cast
,但担心
cast
也会效率低下

那么,我该怎么办

最坏的情况是,我制作2个程序,1个takes数组,另一个takes列表,然后重载?

Reverse()
将直接基于列表生成一个
IEnumerable
;不涉及复制。试一试,如果只进行迭代,可能效率更高。

Array.Reverse()
是静态的:

T[] arr = ...
Array.Reverse(arr); // in-place
列表。反向
不是:

List<T> list = ...
list.Reverse(); // in-place too
List=。。。
list.Reverse();//也到位了

还有一种LINQ扩展方法:

IList<T> ilist = ...
IEnumerable<T> e = ilist.AsEnumerable();
IEnumerable<T> result = e.Reverse(); // not in-place
IList IList=。。。
IEnumerable e=ilist.AsEnumerable();
IEnumerable result=e.Reverse();//不到位

如果您想要一个采用IList的就地反向方法,而不仅仅是一个列表或数组,那么您必须自己编写它。这不是一个特别复杂的算法,所以我想你自己也可以编写这样一个方法。

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);
}
只需添加范围检查/前提条件/不变量等。此外,列表可能效率低下,因为它需要随机访问列表的内容,但我认为您无法使用“常规武器”(即不使用反射和直接内存操作)来解决此问题

因此,我的建议是:重载是一种方法。

Linq Reverse()扩展方法忽略了一个明显的优化,它总是创建一个临时数组来存储元素以反转它们。这对于列表或数组来说太昂贵了

如果需要在位反转,则可以编写一个扩展方法来选择适当的reverse()方法:

公共静态类MyExtensions{
公共静态无效反向(此IList源){
如果(来源是列表){
((List)source.Reverse();
}
else if(源为T[]){
Array.Reverse((T[])源;
}
否则抛出新的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;
            }
        }
    }
}
公共静态类MyExtensions{
公共静态IEnumerable反向(此IEnumerable源){
如果(源为IList){
变量列表=(IList)源;
for(int ix=list.Count-1;ix>=0;--ix){
收益回报表[ix];
}
}
否则{
foreach(可枚举中的var项。反向(源)){
收益回报项目;
}
}
}
}

这可能会帮助您解决
IList
问题。也许放弃使用像Array和List这样的具体类,转而使用它们的接口是个好主意?也许IEnumerable适合您的需要?总之,您始终可以从IEnumerable中取回列表或数组。@J0HN不,使用
IEnumerable时,您无法取回
列表
数组
。您可以创建一个新列表或一个新数组,但这非常简单different@Servy我从来没有想过它会是完全相同的数组。是的,它肯定会构建新的阵列,但是,避免这种阵列重构不是一种过早的优化吗?只有OP知道:)@J0HN当你说取回“你的数组”而不是“一个数组”时,它确实暗示了相同的一个,是的。此外,OP确实指出,在适当的位置进行反向操作非常重要。这部分是因为他引用了反向重载,该重载使用两个
int
参数,只允许反转数组的一部分而不是整个数组。除了优化之外,还可能有其他原因希望在适当的位置执行此操作(因为影响您可能无法控制的对对象的其他引用很重要)。
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();
    }
}
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;
            }
        }
    }
}