【问题标题】:Foreach not working properlyForeach 无法正常工作
【发布时间】:2014-02-05 08:15:17
【问题描述】:

我正在尝试编写一个从 Unity .config 文件中获取一些元素的方法。每个元素都有 type 和 mapTo 属性,我正在获取它们的字符串值,获取我需要的子字符串并将它们放在两个单独的列表中。之后我想在一些数据网格中写入列表的内容。

问题在于,在完成所有 foreach 循环后,代码会返回到用于检查单个寄存器的代码中,并再次进入其他两个以获取类型和 mapTo 值。 换句话说,在列表中,我得到了无数的字符串值,而不是只得到一次。 我是一个初学者,我已经尝试了很多东西,但没有任何接缝可以完成工作。 有人知道我做错了什么吗? C#中的方法代码如下:

private void ReadAdvancedConfigFile(string path)
        {
            XElement root = null;
            root = XElement.Load(new XmlTextReader(path));

            if (root != null)
            {
                XNamespace ns = "http://schemas.microsoft.com/practices/2010/unity";
                var registers = root.Element(ns + "unity").Element(ns + "container").Descendants(ns + "register");

                if (registers.Count() > 0)
                {
                    var tipList = registers.Select(x => x.Attribute("type").Value);
                    var mapToList = registers.Select(x => x.Attribute("mapTo").Value);
                    List<string> listresult = new List<string>();
                    List<string> listresultm = new List<string>();

                    foreach (var reg in registers)
                    {
                        foreach (var tpl in tipList)
                        {
                            var end = tpl.IndexOf(',');
                            var start = tpl.LastIndexOf('.', (end == -1 ? tpl.Length - 1 : end)) + 1;
                            var result = tpl.Substring(start, (end == -1 ? tpl.Length : end) - start);
                            listresult.Add(result);
                        }
                        foreach (var mpl in mapToList)
                        {
                            var endm = mpl.IndexOf(',');
                            var startm = mpl.LastIndexOf('.', (endm == -1 ? mpl.Length - 1 : endm)) + 1;
                            var resultm = mpl.Substring(startm, (endm == -1 ? mpl.Length : endm) - startm);
                            listresultm.Add(resultm);
                        }

                        int maxLenList = Math.Max(listresult.Count, listresultm.Count);
                        for (int i = 0; i < maxLenList; i++)
                        {
                            if (i < listresult.Count && i < listresultm.Count)
                            {
                                _obsCollection.Add(new Tuple<string, string>(listresult[i], listresultm[i]));
                            }
                            else if (i >= listresult.Count)
                            {
                                _obsCollection.Add(new Tuple<string, string>(string.Empty, listresultm[i]));
                            }
                            else if (i >= listresultm.Count)
                            {
                                _obsCollection.Add(new Tuple<string, string>(listresultm[i], string.Empty));
                            }
                        }
                    }
                    tabela.ItemsSource = _obsCollection;
                }
            }
        }  

方法从名为 Load 的按钮调用,该按钮从文件系统中的某个位置找到 Unity.config 文件,如下所示:

 private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fDialog = new OpenFileDialog();

            fDialog.Title = "Open XML file";
            fDialog.Filter = "XML files|*.config";
            fDialog.InitialDirectory = @"C:\";

            bool? control = fDialog.ShowDialog();
            if (control.Value)
            {
                var filePath = fDialog.FileName;
                ReadAdvancedConfigFile(filePath);
            }

        }

在 Unity.config 中是这种格式的 XML 文件(我删除了大部分元素,为了这里的一些空间,它也可以使用):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
    </configSections>

    <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">

        <container name="container">

            <register name="configService" type="Web.Common.Interfaces.IConfigService, Web.Common"
                      mapTo="Web.Common.Services.ConfigServiceImpl, Web.Common">
                <lifetime type="singleton" />
                <constructor>
                    <param name="res" value="Resources.ClientStrings"> </param>
                    <param name="configFile" value="webclient.config"> </param>
                </constructor>
                <!--<property name="LocalisationService" dependencyName="LocalisationService" />-->
                <!--This is a property injection from the language plugin -->
            </register>

            <register name="scaleCoefConfigService" type="Web.WebClient.Services.IScaleCoefConfigService, Web.WebClient.TDMSWebApp"
                      mapTo="Web.WebClient.Services.Implementations.ScaleCoefConfigServiceImpl, Web.WebClient.TDMSWebApp">
                <lifetime type="singleton" />
                <constructor>
                    <param name="configService">
                        <dependency name="configService"/>
                    </param>
                </constructor>
            </register>

            <register name="sessionService" type="Web.Common.Interfaces.ISessionService, Web.Common" 
                      mapTo="Web.Common.Services.SessionServiceImpl, Web.Common">
                <lifetime type="singleton" />
            </register>

            <register name="licenseManagerService" type="Web.Common.Interfaces.ILicenseManagementService, Web.Common"
                      mapTo="Web.Common.Services.LicenseManagementServiceImpl, Web.Common">
                <lifetime type="singleton" />
            </register>
        </container>
    </unity>
</configuration>

【问题讨论】:

  • 我们无法在您的代码中找到错误,即使我们无法运行它。请学习调试您的代码:youtube.com/watch?v=C0vDKXIq_9A
  • 正如 Euphoric 所说:缩小代码范围。创建一个演示项目,删除所有不会导致问题的代码并将其发布在此处。
  • 我正在调试,但仍然无法意识到问题所在。无论如何,谢谢...我会继续尝试:)
  • @PatrickHofman 好的,我将在下一篇文章中尝试这样做。希望我能够让您更好地了解代码。 :)
  • 这次试试吧。当我们无事可做时,您希望我们如何帮助您?

标签: c# foreach unity-container infinite-loop


【解决方案1】:

在我看来,好像您不需要 foreach 循环。当您使用 LINQ 进行查询时,您已经获取了所有 'type' 和 'mapTo' 属性:

var tipList = registers.Select(x => x.Attribute("type").Value);
var mapToList = registers.Select(x => x.Attribute("mapTo").Value);

这有效地为您提供了“寄存器”中 xelements 的所有属性。 您甚至没有在循环中使用 var 'reg'...

【讨论】:

  • 感谢您的回复。我会立即尝试并让您知道它是否有效:)
  • 删除foreach (var reg in registers)后它确实有效
  • @Reinder 尝试删除 foreach(var reg in registers),但问题仍然存在。我完全搞砸了一些非常糟糕的事情。 :-/ 但是你是对的,那个循环没有做任何事情,这完全没有必要。退出两个 foreach 循环后,它返回到 var tipList 和 var mapToList 并一次又一次地复制列表中的值。
【解决方案2】:

我调整了你的代码,现在它可以工作了(删除foreach):

XElement root = null;
root = XElement.Load(new XmlTextReader(path));

if (root != null)
{
    XNamespace ns = "http://schemas.microsoft.com/practices/2010/unity";
    var registers = root.Element(ns + "unity").Element(ns + "container").Descendants(ns + "register");

    if (registers.Count() > 0)
    {
        var tipList = registers.Select(x => x.Attribute("type").Value);
        var mapToList = registers.Select(x => x.Attribute("mapTo").Value);
        List<string> listresult = new List<string>();
        List<string> listresultm = new List<string>();

        foreach (string tpl in tipList)
        {
            int end = tpl.IndexOf(',');
            int start = tpl.LastIndexOf('.', (end == -1 ? tpl.Length - 1 : end)) + 1;
            string result = tpl.Substring(start, (end == -1 ? tpl.Length : end) - start);
            listresult.Add(result);
        }

        foreach (string mpl in mapToList)
        {
            int endm = mpl.IndexOf(',');
            int startm = mpl.LastIndexOf('.', (endm == -1 ? mpl.Length - 1 : endm)) + 1;
            string resultm = mpl.Substring(startm, (endm == -1 ? mpl.Length : endm) - startm);
            listresultm.Add(resultm);
        }

        int maxLenList = Math.Max(listresult.Count, listresultm.Count);

        for (int i = 0; i < maxLenList; i++)
        {
            if (i < listresult.Count && i < listresultm.Count)
            {
                _obsCollection.Add(new Tuple<string, string>(listresult[i], listresultm[i]));
            }
            else if (i >= listresult.Count)
            {
                _obsCollection.Add(new Tuple<string, string>(string.Empty, listresultm[i]));
            }
            else if (i >= listresultm.Count)
            {
                _obsCollection.Add(new Tuple<string, string>(listresultm[i], string.Empty));
            }
        }
    }
}

【讨论】:

  • 是的,这完全有效,谢谢:) 所以我有一个问题。您将几乎所有 var 更改为 string 和 int 类型。有什么问题吗?如果我们使用太多 var 来定义或类似的东西,会有问题吗?附言我现在有一个新问题,我没有从数据网格中的列表中获取这些字符串,而是得到了一些行。但这是全新的问题:)
  • 抱歉,我更改了 var 变量只是为了让自己弄清楚发生了什么。我个人不喜欢var
  • @nemo_87:在一个新问题中发布一个示例,我会看看。
  • 哦,好吧,我在想,使用太多 var 可能不好。 :) 我现在会发新的,我只需要更好地研究代码,所以我可以问一个正确的问题。 :)
  • 我已经发布了新帖子并将其命名为:将字符串值从列表传递到数据网格将尝试解决这个问题,但如果你有一些想法,非常感谢:)
猜你喜欢
  • 2014-02-15
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
  • 2021-10-15
  • 1970-01-01
  • 2016-12-01
  • 2020-05-05
相关资源
最近更新 更多