C# 有没有一种方法可以重用具有不同端点参数的循环?
请不要被代码墙吓倒!我的问题是:我是否可以以某种方式重用代码,并将我想要的任何参数放在//DoSomething的位置?我不想复制和粘贴相同的代码墙,我想减少重复性并使其更易于维护。我想知道这个问题,但我没有看到一个简单的解决办法,我也找不到一个C# 有没有一种方法可以重用具有不同端点参数的循环?,c#,C#,请不要被代码墙吓倒!我的问题是:我是否可以以某种方式重用代码,并将我想要的任何参数放在//DoSomething的位置?我不想复制和粘贴相同的代码墙,我想减少重复性并使其更易于维护。我想知道这个问题,但我没有看到一个简单的解决办法,我也找不到一个 for (int i = 0; i < treeListViewDatabase.SelectedObjects.Count; i++) { if (treeListViewDatabase
for (int i = 0; i < treeListViewDatabase.SelectedObjects.Count; i++)
{
if (treeListViewDatabase.SelectedObjects[i] is NodeValueWithNodes rootNode)
{
for (int m = 0; m < rootNode.ChildTreeViewSets.Count; m++)
{
if (rootNode.ChildTreeViewSets[m] is NodeValueWithNodes childNodeWithNode)
{
for (int k = 0; k < childNodeWithNode.ChildTreeViewSets.Count; k++)
{
if (childNodeWithNode.ChildTreeViewSets[k] is NodeValueWithNodes secondChildNodeWithNode)
{
for (int p = 0; p < secondChildNodeWithNode.ChildTreeViewSets.Count; p++)
{
if (secondChildNodeWithNode.ChildTreeViewSets[p] is NodeValueWithDevices thirdChildNodeWithDevices)
{
for (int r = 0; r < thirdChildNodeWithDevices.ChildDeviceSet.Count; r++)
{
if (dataRows.Contains(thirdChildNodeWithDevices.ChildDeviceSet[r]))
{
dataRows.Remove(thirdChildNodeWithDevices.ChildDeviceSet[r]);
}
// DoSomething()
}
}
}
}
if (childNodeWithNode.ChildTreeViewSets[k] is NodeValueWithDevices secondChildNodeWithDevice)
{
for (int r = 0; r < secondChildNodeWithDevice.ChildDeviceSet.Count; r++)
{
if (dataRows.Contains(secondChildNodeWithDevice.ChildDeviceSet[r]))
{
dataRows.Remove(secondChildNodeWithDevice.ChildDeviceSet[r]);
}
// DoSomething();
}
}
}
}
if (rootNode.ChildTreeViewSets[m] is NodeValueWithDevices childNodeDevices)
{
for (int n = 0; n < childNodeDevices.ChildDeviceSet.Count; n++)
{
if (dataRows.Contains(childNodeDevices.ChildDeviceSet[n]))
{
dataRows.Remove(childNodeDevices.ChildDeviceSet[n]);
}
// DoSomething();
}
}
}
}
if (treeListViewDatabase.SelectedObjects[i] is NodeValueWithDevices rootNodeWithDevices)
{
for (int n = 0; n < rootNodeWithDevices.ChildDeviceSet.Count; n++)
{
if (dataRows.Contains(rootNodeWithDevices.ChildDeviceSet[n]))
{
dataRows.Remove(rootNodeWithDevices.ChildDeviceSet[n]);
}
// DoSomething();
}
}
}
for (int i = 0; i < dataRows.Count; i++)
{
// DoSomething();
}
for(int i=0;i
*编辑*
按照人们的建议,我已经完全更改了代码。代码的箭头式外观被一个简单的递归所取代。这个实现使我的问题不存在,因为我可以循环通过数据行执行必要的操作
private void TraverseTreeView(IList selectedObjects, List<DataRow> dataRows)
{
if (selectedObjects == null)
{
return;
}
foreach (var selectedObject in selectedObjects)
{
if (selectedObject is NodeValueWithNodes withNodes)
{
TraverseTreeView(withNodes.ChildTreeViewSets, dataRows);
}
if (selectedObject is NodeValueWithDevices withDevices)
{
TraverseTreeView(withDevices.ChildDeviceSet, dataRows);
}
if (selectedObject is DataRow dataRow && !dataRows.Contains(dataRow))
{
dataRows.Add(dataRow);
}
}
}
private void TraverseTreeView(IList selectedObjects,List dataRows)
{
如果(SelectedObject==null)
{
回来
}
foreach(selectedObject中的变量selectedObject)
{
如果(selectedObject是NodeValueWithNodesWithNodes)
{
TraverseTreeView(withNodes.ChildTreeView、dataRows);
}
如果(selectedObject是nodeValue with devices with devices)
{
TraverseTreeView(withDevices.ChildDeviceSet,dataRows);
}
if(selectedObject为DataRow DataRow&!dataRows.Contains(DataRow))
{
添加(dataRow);
}
}
}
您可以使用。它可能看起来像这样:
public void TraverseTree(TreeListView root, Action<T> toDo)
{
//big set of loops goes in here
//DoSomething(); is replaced with:
toDo(rootNodeWithDevices.ChildDeviceSet[n]);
}
Traverse(treeListViewDatabase, (node) => {
//code for whatever you want to do goes in here
});
var items = treeListViewDatabase.SelectedObjects.
Where(o => o is NodeValueWithNodes).
Select(o => o.ChildTreeViewSets).
Where(o => o is NodeValueWithNodes).
Select(o => o.ChildTreeViewSets).
Where(o => o is NodeValueWithNodes).
Select(o => o.ChildTreeViewSets).
Where(o => o is NodeValueWithDevices).
Select(o => o.ChildDeviceSet);
foreach(var item in items)
{
if (dataRows.Contains(item))
dataRows.Remove(item);
//DoSomething();
}
var items = Traverse(treeListViewDatabase).
Where(o => o is NodeValueWithDevices).
Select(o => o.ChildDeviceSet);
foreach(var item in items)
{
if (dataRows.Contains(item))
dataRows.Remove(item);
//DoSomething();
}
我还倾向于首先像这样重新编写循环的初始集合:
public void TraverseTree(TreeListView root, Action<T> toDo)
{
//big set of loops goes in here
//DoSomething(); is replaced with:
toDo(rootNodeWithDevices.ChildDeviceSet[n]);
}
Traverse(treeListViewDatabase, (node) => {
//code for whatever you want to do goes in here
});
var items = treeListViewDatabase.SelectedObjects.
Where(o => o is NodeValueWithNodes).
Select(o => o.ChildTreeViewSets).
Where(o => o is NodeValueWithNodes).
Select(o => o.ChildTreeViewSets).
Where(o => o is NodeValueWithNodes).
Select(o => o.ChildTreeViewSets).
Where(o => o is NodeValueWithDevices).
Select(o => o.ChildDeviceSet);
foreach(var item in items)
{
if (dataRows.Contains(item))
dataRows.Remove(item);
//DoSomething();
}
var items = Traverse(treeListViewDatabase).
Where(o => o is NodeValueWithDevices).
Select(o => o.ChildDeviceSet);
foreach(var item in items)
{
if (dataRows.Contains(item))
dataRows.Remove(item);
//DoSomething();
}
如果必须这样做,我会添加一个ToList()
调用,以避免在迭代时修改此序列
做了这么多之后,我将进一步研究如何构建一个递归方法,以避免如此多的重复。例如,我不确定您有哪个第三方TreeListView控件,但如果它是标准TreeView控件,我可能会这样做:
public IEnumerable<TreeNode> Traverse(TreeView source)
{
// See Local Functions:
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions
IEnumerable<TreeNode> innerTraverse(TreeNodeCollection root)
{
foreach(var node in root)
{
yield return node;
foreach(var node in innerTraverse(root))
{
yield return node;
}
}
}
return innerTraverse(source.nodes));
}
这并不完全相同-我们还没有考虑选择