首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用图IEnumerator

调用图IEnumerator
EN

Stack Overflow用户
提问于 2012-07-10 03:41:51
回答 1查看 321关注 0票数 2

我必须为像Id = Id(Param);这样的表达式实现一个调用图,这不是问题。

现在我必须实现一个枚举器,它一次列出一个满足依赖顺序的调用中的所有拓扑顺序。

问题就出在这里。

这是调用图的一个简单节点:

代码语言:javascript
复制
class CallGraphNode
{
    private string name;
    public List<CallGraphNode> dependents = new List<CallGraphNode>();
    public int dependencies;
    private bool executed = false;
    public bool Executable { get { return dependencies == 0; } }
    public bool Executed { get { return executed; } set { executed = value; } }

    public CallGraphNode(string name)
    {
        this.name = name;
        dependencies = 0;    
    }

    public override string ToString()
    {
        return name;
    }

    public void AddDependent(CallGraphNode n)
    {
        dependents.Add(n);
    }          
}

这是调用图类本身:

代码语言:javascript
复制
class CallGraph : IEnumerable<List<CallGraphNode>>
{
    public List<CallGraphNode> nodes = new List<CallGraphNode>();

    public void AddNode(CallGraphNode n)
    {
        nodes.Add(n);
    }

    public static void Show(IEnumerable<CallGraphNode> n)
    {
        foreach (CallGraphNode node in n)
        {
            Console.Write("{0} ", node);
        }
        Console.WriteLine();
    }

    static IEnumerable<List<CallGraphNode>> EnumerateFunctions(List<CallGraphNode> executable, List<CallGraphNode> res)
    {
        if (executable.Count == 0)
            yield return res;
        else foreach (CallGraphNode n in executable)
            {
                if (!n.Executed)
                    res.Add(n);
                List<CallGraphNode> next_executable = new List<CallGraphNode>(executable);
                executable.Remove(n);
                foreach (CallGraphNode m in n.dependents)
                    if (--m.dependencies == 0)
                        next_executable.Add(m);
                foreach (List<CallGraphNode> others in EnumerateFunctions(next_executable, res))
                    yield return others;
                foreach (CallGraphNode m in n.dependents)
                    m.dependencies++;
                if (!n.Executed)
                    res.Remove(n);
            }
    }

    IEnumerator<List<CallGraphNode>> IEnumerable<List<CallGraphNode>>.GetEnumerator()
    {
        List<CallGraphNode> executable = new List<CallGraphNode>();
        foreach (CallGraphNode n in nodes)
            if (n.Executable || n.Executed)
                executable.Add(n);
        List<CallGraphNode> output = new List<CallGraphNode>();
        foreach (List<CallGraphNode> list in EnumerateFunctions(executable, output))
            yield return list;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    { throw new NotImplementedException(); }
}

现在,问题是它就是不起作用。当我尝试创建IEnumerator并将GetEnumerator()返回值赋给它时,我得到了一个强制转换错误,老实说,这是我在尝试这样做时所期望的:

代码语言:javascript
复制
IEnumerator<List<CallGraphNode>> lt = cg.GetEnumerator();

然后我试过了:

代码语言:javascript
复制
System.Collections.Generic.List<CallGraphNode>.Enumerator en = cg.nodes.GetEnumerator();

这是可行的,但是EnumerateFunctions方法永远不会被调用,并且枚举器只包含图形节点的原始列表。

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-10 03:45:21

问题是您同时使用explicit interface implementation实现IEnumerable<T>IEnumerable

您可能想要更改此声明:

代码语言:javascript
复制
IEnumerator<List<CallGraphNode>> IEnumerable<List<CallGraphNode>>.GetEnumerator()

要成为一个“普通”的接口实现:

代码语言:javascript
复制
public IEnumerator<List<CallGraphNode>> GetEnumerator()

或者,您可以坚持使用显式接口实现,但使用:

代码语言:javascript
复制
IEnumerable<List<CallGraphNode>> sequence = cg;
IEnumerator<List<CallGraphNode>> lt = sequence.GetEnumerator();
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11401975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档