【问题标题】:How to simplify this code using .net 3.5/C#如何使用 .net 3.5/C# 简化此代码
【发布时间】:2011-07-07 17:33:47
【问题描述】:

我在C# and .net 3.5 中有以下代码,它工作正常,但需要知道这是否可以简化可能是使用 Linq 或其他东西?基本上我正在读取一个 xml 文件来获取列名。然后尝试复制字典对象中的列和序列属性,如果“列的isactive属性为”真“。我在代码的其他部分使用这个字典对象。我循环遍历元素,然后遍历属性并查找列那些是活动的,如果活动我存储序列,最后将列和序列添加到字典中。

var doc = XDocument.Load("DataStructure.xml");
var cols = doc.XPathSelectElements("/datastructure/" + sPageName + "/columns");
Dictionary<string, int> columns = new Dictionary<string, int>();
bool bAddData = true;
int sSequence = 0;

foreach (var col in cols.Elements())
{
    foreach (XAttribute at in col.Attributes())
    {
        if (at.Name.ToString().ToLower().Equals("isactive") && at.Value.ToString() != "true")
        {
            bAddData = false;
            break;
        }

        bAddData = true;                    
        if (at.Name.ToString().ToLower().Equals("sequence"))
        {
            sSequence = Convert.ToInt32(at.Value.ToString());
            break;
        }
    }
    if (bAddData)
    {
        columns.Add(col.Name.ToString(), sSequence);
    }
}

我确信这是非常糟糕的代码,但我想知道如何改进它。这是xml数据文件。如果我需要重组 xml 以使其变得简单,我可以。

<?xml version="1.0" encoding="utf-8" ?>
<datastructure>
  <MyPage>
    <columns>
      <number isactive="true" sequence="1" />
      <curr_code isactive="true" sequence="2" />
      <curr_desc isactive="true" sequence="3" />
      <tradecurrvalue isactive="true" sequence="4" />
      <selectcurrvalue isactive="true" sequence="5" />
    </columns>    
  </MyPage>
</datastructure>

【问题讨论】:

  • 为什么?您已经拥有“比 LINQ 更快”的代码版本。
  • @BoltClock,C# 3.5。我以为我没有充分利用 C# 3.5。
  • @Mrchief,我认为 LINQ 可以简化,但可能会更慢且更不灵活。我说的对吗?
  • @user465876:C# 3.5 不存在。它是 3.0 或 4.0...
  • 它可能会减少代码行数并产生更短的语法,但它确实会引入开销。最终它会在某​​个时候被翻译成foreach。 LINQ 与 lambdas 结合确实可以产生优雅的代码。是不是更简单?这是主观的!

标签: c# .net linq .net-3.5


【解决方案1】:

我认为应该这样做:

var doc = XDocument.Load("DataStructure.xml");
var cols = doc.XPathSelectElements("/datastructure/" + sPageName + "/columns");

Dictionary<string, int> columns =
  cols.Elements()
  .Where(c => c.Attribute("isactive").Value == "true")
  .ToDictionary(
    c => c.Name.ToString(),
    c => Int32.Parse(c.Attribute("sequence").Value)
  );

编辑:

出于好奇,一旦我弄清楚原始代码实际做了什么以及如何最好地使用 XElement 类中的方法,我想知道在不使用 LINQ 的情况下可以对原始代码做什么,然后我得出了这个结论:

var doc = XDocument.Load("DataStructure.xml");
var cols = doc.XPathSelectElements("/datastructure/" + sPageName + "/columns");
Dictionary<string, int> columns = new Dictionary<string, int>();

foreach (var col in cols.Elements()) {
  if (col.Attribute("isactive").Value == "true") {
    columns.Add(col.Name.ToString(), Int32.Parse(col.Attribute("sequence").Value));
  }
}

【讨论】:

  • 我发现这比原始版本更难阅读。
  • @Charles:我实际上发现它更容易理解。我花了一段时间才弄清楚原始代码在做什么。我现在也简化了一点,使用 XElement 中的方法来查找属性而不是 LINQ 扩展。
  • 哈哈@Guffa。你觉得更容易跟随?哥们,你写的代码。如果只是出于这个原因,我会觉得它很容易理解。
  • @Tundey:将其写为查询使其更直接。原始代码实际上过于复杂,因此不使用 LINQ 也可以使其更具可读性。
  • 我认为这不正确。 c.Attribute("isactive").Value != "true" 应该是 c.Attribute("isactive").Value == "true"。
【解决方案2】:
var doc = XDocument.Load("DataStructure.xml");
var cols = doc.XPathSelectElements("/datastructure/MyPage/columns").Descendants();
var columns = cols.Where(e => e.Attribute("isactive").Value.ToLower() == "true").ToDictionary(e => e.Name, e => int.Parse(e.Attribute("sequence").Value));

【讨论】:

  • 我发现这个解决方案简短而优雅。想知道上面提供的这个和其他解决方案是否有任何限制。
  • 我不这么认为。但是,如果您并不总是使用 isactive,则必须在 where 子句中检查它。像这样的东西,您可能需要进行调整以使其准备好生产。这一切都取决于您传入的 xml 以及需要哪些属性。
  • xml 是一个配置文件,它的所有属性都始终为 value/null。
  • 我对这个解决方案的评价很高,但会保留这个 LINQ 解决方案以备将来使用。我现在将使用我的代码,但 Guffa 发布了一个简化版本 :) 感谢 Michael 抽出宝贵时间!!
【解决方案3】:

你可以试试这样的

cols.Elements().Where(
                e =>
                    {
                        var attribute = e.Attribute("isactive");
                        return attribute != null &&
                               attribute.Value.ToString().Equals("true", StringComparison.CurrentCultureIgnoreCase);
                    })
                .ToDictionary(e => e.Name.ToString(),
                              e => Convert.ToInt32(e.Attribute("sequence").Value.ToString()));

【讨论】:

  • @bdowden:你为什么会在这里关心StringComparison.CurrentCultureIgnoreCase?微小的速度优化值得额外的四行代码吗?只是好奇。
  • 我习惯在多语言系统中工作。我把它放进去只是因为我习惯了。
猜你喜欢
  • 1970-01-01
  • 2017-12-19
  • 1970-01-01
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多