使用Func捕获类属性

时间:2012-11-22 01:05:08

标签: c# lambda closures graph-algorithm func

我正在努力实现图表类。在类中,我了解到广度优先和深度优先遍历是相同的算法,除了存储遍历节点的队列和堆栈分别使用。所以我将所有逻辑放入一个由DepthFirstSearch()调用的Traversal()方法中,该方法作为ADT传入一个堆栈。

public void DepthFirstSearch(GraphNode<T> root)
{
    Stack<GraphNode<T>> s = new Stack<GraphNode<T>>();

    Action<GraphNode<T>> insert = s.Push;
    Func<GraphNode<T>> retrieve = s.Pop;
    //Func<int> stackCount = s.Count; Cannot implicitly convert type 'int' to System.Func<int>' error
    Func<int> stackCount = () => s.Count;

    Traversal(root, insert, retrieve, stackCount);
}

我假设我不能将s.Count传递给委托,因为它是一个类属性?因此,为了解决它,我使用lambda封闭了该属性。但任何人都可以解释为什么我需要lambda for s.Count而不是s.Pop或s.Push?感谢。

1 个答案:

答案 0 :(得分:3)

原因是因为Stack<T>.PushStack<T>.Pop 已经与委托类型(Func<TResult>Action<T>兼容的函数,其中TResultT与您尝试分配方法的Stack<T>的通用类型参数(在您的情况下为GraphNode<T>)匹配。如果它们不兼容,则需要使用lambda函数或其他类型的包装器委托将方法分配给委托变量。

虽然类属性技术上由getter和setter方法组成,但在C#中,这些细节被抽象掉,要求你在lambda函数中包装一个class属性。另外,根据下面Servy的评论,编译器将无法轻易确定您是否尝试将getter或setter分配给委托变量。