gpt4 book ai didi

c# - 调用图 IEnumerator

转载 作者:行者123 更新时间:2023-12-02 05:37:55 25 4
gpt4 key购买 nike

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

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

问题来了。

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

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);
}
}

这是调用图类本身:

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() 返回值时,我收到了一个转换错误,这正是我在尝试这样做时所期望的:

IEnumerator<List<CallGraphNode>> lt = cg.GetEnumerator();

然后我尝试了:

System.Collections.Generic.List<CallGraphNode>.Enumerator en = cg.nodes.GetEnumerator();

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

有什么想法吗?

最佳答案

问题是你正在实现两者 IEnumerable<T>IEnumerable使用 explicit interface implementation .

您可能想要更改此声明:

IEnumerator<List<CallGraphNode>> IEnumerable<List<CallGraphNode>>.GetEnumerator()

成为一个“正常”的接口(interface)实现:

public IEnumerator<List<CallGraphNode>> GetEnumerator()

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

IEnumerable<List<CallGraphNode>> sequence = cg;
IEnumerator<List<CallGraphNode>> lt = sequence.GetEnumerator();

关于c# - 调用图 IEnumerator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11401975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com