对单个对象使用LINQ被认为是一种糟糕的做法

本文关键字:一种 对象 单个 LINQ 认为是 | 更新日期: 2023-09-27 18:23:36

我不是说这个问题太主观

我在谷歌上搜索了一段时间,但没有得到具体的答案来解决这个问题。问题是,我觉得我有点沉迷于LINQ。我已经使用LINQ在列表上查询了,还有其他一些事情,比如将LINQ用于Sql、Xml等等。但后来我突然想到:"如果我用它来查询一个对象呢?"所以我这么做了。这似乎是错误的,就像试图用手榴弹发射器杀死一只苍蝇一样。尽管我们都同意这将是艺术上的愉快看到。


我认为它非常可读,我不认为有任何性能问题,但让我给你看一个例子。

在web应用程序中,我需要从配置文件(web.config)中检索一个设置。但如果密钥不存在,这个设置应该有一个默认值。此外,我需要的值是十进制,而不是字符串,这是ConfigurationManager.AppSettings["myKey"]的默认返回值。此外,我的数字不应该超过10,也不应该是负数。我知道我可以写这个:

string cfg = ConfigurationManager.AppSettings["myKey"];
decimal bla;
if (!decimal.TryParse(cfg,out bla))
{
    bla = 0; // 0 is the default value
}
else
{
    if (bla<0 || bla>10)
    {
        bla = 0;
    }
}

这本书并不复杂,也不复杂,而且很容易阅读。然而,我喜欢这样做:

// initialize it so the compiler doesn't complain when you select it after
decimal awesome = 0; 
// use Enumerable.Repeat to grab a "singleton" IEnumerable<string>
// which is feed with the value got from app settings
awesome = Enumerable.Repeat(ConfigurationManager.AppSettings["myKey"], 1)
    // Is it parseable? grab it 
    .Where(value => decimal.TryParse(value, out awesome))
    // This is a little trick: select the own variable since it has been assigned by TryParse
    // Also, from now on I'm working with an IEnumerable<decimal>
    .Select(value => awesome)
    // Check the other constraints
    .Where(number => number >= 0 && number <= 10)
    // If the previous "Where"s weren't matched, the IEnumerable is empty, so get the default value
    .DefaultIfEmpty(0)
    // Return the value from the IEnumerable
    .Single();

如果没有评论,它看起来是这样的:

decimal awesome = 0; 
awesome = Enumerable.Repeat(ConfigurationManager.AppSettings["myKey"], 1)
    .Where(value => decimal.TryParse(value, out awesome))
    .Select(value => awesome)
    .Where(number => number >= 0 && number <= 10)
    .DefaultIfEmpty(0)
    .Single();

我不知道是不是只有我一个人在这里,但我觉得第二种方法比第一种方法更"有机"。由于LINQ,它不容易调试,但我想它是非常防故障的。至少这是我写的。无论如何,如果您需要调试,您可以在linq方法中添加大括号和返回语句,并对此感到高兴

我已经做了一段时间了,这感觉比做事更自然"逐行,循序渐进"。另外,我只指定了一次默认值。它写在一行,上面写着DefaultIfEmpty,所以很简单。

另一个好处是,如果我注意到查询将比我在那里写的查询大得多,我肯定不会这么做。相反,我将linqglory分成更小的部分,这样它将更容易理解和调试。

我发现看到变量赋值并自动思考更容易:这就是设置这个值所必须做的,而不是查看if、elses、switch等,并试图弄清楚它们是否是公式的一部分。

我认为,它可以防止开发人员在错误的地方编写不想要的副作用。

但最终,有些人可能会说它看起来非常黑客,或者太神秘

所以我手头有个问题:

对单个对象使用LINQ是否被认为是一种糟糕的做法

对单个对象使用LINQ被认为是一种糟糕的做法

我同意,但这实际上取决于偏好。它肯定有缺点,但我将把这件事留给你。不过,您的原始代码可能会变得简单得多。

string cfg = ConfigurationManager.AppSettings["myKey"];
decimal bla;
if (!decimal.TryParse(cfg,out bla) || bla < 0 || bla > 10)
    bla = 0; // 0 is the default value

这是因为"短路"评估,这意味着一旦发现第一个真实条件,程序将停止检查其他条件。

相关文章: