English 中文(简体)
我如何能动态地把一种条件和一种方法带给一种复读的方法
原标题:How can I dynamically pass a condition and a method to a recursive method

我想这样作一个方法。

public dynamic Traverse(dynamic entity, conditions, method)
{
    foreach (var propInfo in GetTraversableProperties(entity))
    {
        if (condition) method(propInfo.GetValue(etc));
        Traverse(propInfo, condition, method);
    }
    return entity;
}

我如何能够这样做? 将条件和方法作为参数的辛迪加是什么? 此外,使条件成为一种方法并检查其返回价值是否更有意义?

最佳回答

你的方法,以及加里的答案,都是完全合理的方法,可以重新界定对物体进行复读的抽象概念。 然而,我看到四个潜在的问题。 也许不是了解你的准确情况,或许是你们的不问问题,或者也许你们应当考虑:

首先,用你正在读写的图表走得太长。 您暗中做了“深度第一<>>->查询,即便在支持尾声再造的建筑中,你的方法也不可能轻易地加以重复,因此,你冒着摆脱警钟的风险。

第二,你假定图表是杂质;如果图表是空洞的,你肯定会离开 st空间。

Third, I don t see why the traversal algorithm returns an entity. Why isn t this method void? Or, if you are using the return as an accumulator to accumulate the value computed by the traversal, then why does the recursive step not do something with the entity returned?

第四,你在此似乎有点关切。 打电话者负责确定(1) 图表的根源是什么,(2) 每一节点应做什么。 但是,被点击者负责(3)把哪些物体重新拿到。 这对我来说似乎很奇怪。 打电话者正在提供起点;打电话者在如何继续工作方面是否有发言权?

我通常解决这个问题如下:

  • Use an explicit stack allocated on the heap rather than using the call stack for control flow
  • Track nodes I ve visited before and do not re-visit them
  • Have the caller determine when an object has traversable children. If the caller wishes the traversal to "bottom out" in the base case then the caller can return an empty set of children.

如果我想要一个蓄谋者的话,我就可执行像这一简图:

static R DepthFirstGraphAccumulate<T, R>(
    T root, 
    Func<T, IEnumerable<T>> children, 
    Func<T, R, R> accumulate)
{
    var accumulator = default(R);
    var visited = new HashSet<T>();
    var stack = new Stack<T>;
    stack.Push(root);
    while(stack.Count != 0)
    {
        var current = stack.Pop();
        if (!visited.Contains(current))
        {
            visited.Add(current);
            foreach(var child in children(current))
                stack.Push(child);
            accumulator = accumulate(current, accumulator);
        }
    }
    return accumulator;
}

因此,例如,如果我有一幅愤怒的图表,我想总结一下从某个起的节点可以达到的节点,我就说:

int total = DepthFirstGraphAccumulate<Node, int>(
    startNode, 
    node=>node.NeighbouringNodes, 
    (node, sum)=>node.Value + sum);

然而,我被诱惑,在“让我们分开关注”的道路上走了一步,说,犹豫不决,只字不提:

static IEnumerable<T> DepthFirstGraphTraversal<T>(
    T root, 
    Func<T, IEnumerable<T>> children)
{
    var visited = new HashSet<T>();
    var stack = new Stack<T>;
    stack.Push(root);
    while(stack.Count != 0)
    {
        var current = stack.Pop();
        if (!visited.Contains(current))
        {
            visited.Add(current);
            foreach(var child in children(current))
                stack.Push(child);
            yield return current;
        }
    }
}

现在,如果我想对图表中的每一个节点采取一些行动,我只说:

foreach(var node in DepthFirstGraphTraversal<Node>(startNode, n=>n.NeighbouringNodes))
     DoSomething(node);

如果我想表达“每一条与某种条件相对应的东西”的概念,那么我就写了:

var nodes = from node in DepthFirstGraphTraversal<Node>(startNode, n=>n.NeighbouringNodes)
            where condition(node)
            select node;
foreach(var matchingNode in nodes) DoSomething(matchingNode);
问题回答

i 考虑在条件上使用一名富人代表。 至于如何通过方法,这再次会利用代表们。 我想做的是:

public dynamic Traverse(dynamic entity, Func<dynamic, bool> conditions, Action<dynamic> method)
{
    foreach (var propInfo in GetTraversableProperties(entity))
    {
        if (conditions(entity)) method(propInfo.GetValue(etc));
        Traverse(propInfo, conditions, method);
    }
    return entity;
}

Func:

行动:





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...