使用LINQ将项目推入堆栈

时间:2009-10-20 12:29:57

标签: c# linq

我如何以编程方式将字符串数组推入通用堆栈?

字符串数组

 string[] array=new string[]{"Liza","Ana","Sandra","Diya"};

堆叠设置

 public class stack<T>
 {
    private int index;

    List<T> list; 

    public stack()
    {
        list = new List<T>();
        index=-1;

    }

    public void Push(T obj)
    {

        list.Add(obj);
        index++;
    }
 ...........
}

我需要改变什么?

stack<string> slist = new stack<string>();
var v = from vals in array select (p => slist.Push(p));

错误报告:

The type of the expression in the select clause is incorrect.

5 个答案:

答案 0 :(得分:12)

LINQ是一种查询语言/框架。你想在这里执行的是对集合对象的修改而不是查询(选择) - 这肯定是而不是 LINQ的设计目标(甚至能够)

然而,您可能想要做的是为Stack<T>类定义一个扩展方法。请注意,此处使用BCL Stack<T>类型也是有意义的,这正是您所需要的,而不是使用List<T>重新发明轮子。

public static void PushRange<T>(this Stack<T> source, IEnumerable<T> collection)
{
    foreach (var item in collection)
        source.Push(item);
}

然后,您可以执行以下操作:

myStack.PushRange(myCollection);

如果您还没有确信,另一个哲学原因是:LINQ的创建是为了将函数式范例引入C#/ .NET,而函数式编程的核心是无副作用的代码。因此,将LINQ与状态修改代码相结合将是非常不一致的。

答案 1 :(得分:0)

第一个问题是Push返回一个void。选择期望某事物的价值。

您只是在做一个循环,不需要使用链接。

由于堆栈是在内部存储列表,因此您可以通过传递数组来创建列表。

所以在你的情况下

List<string> myList = new List<string>(array); 

创建列表。

答案 2 :(得分:0)

更改

public void Push(T obj)

public T Push(T obj)

并忽略返回值。

免责声明:我不建议像这样的突变。

答案 3 :(得分:0)

试试这个

string[] arr = new string[]{"a","f"};
var stack = new Stack<string>();
arr.ToList().ForEach(stack.Push);

虽然这是“酷”,但并不比for循环更好。

答案 4 :(得分:-1)

Push需要一个返回类型,以便能够在select子句中使用它。实际上,它返回void。我认为,你的例子是对LINQ的可怕滥用。即使它有效,你也会在select子句中使用函数的副作用来完成与select所针对的任务完全无关的事情。如果有一个“ForEach”扩展,那么在这里使用LINQ是合理的,但我会避免它并坚持使用foreach循环。

 foreach (var val in array)
 {
     slist.Push(val);
 }

这在意图上更加清晰,并且不会让人对你想要完成的事情感到头疼。