我并不是说这个问题太主观。
我用谷歌搜索了一段时间,但没有得到解决这个问题的具体答案。问题是,我想我对LINQ有点上瘾了。我已经使用 LINQ 来查询列表,例如使用 Linq to 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 方法中添加大括号和 return 语句,并对此感到满意。
我已经这样做了一段时间了,感觉比做“一行一行,一步一步”的事情要自然得多。另外,我只指定了一次默认值。它写在一行中,DefaultIfEmpty
所以它非常简单。
另一个优点是,如果我注意到查询比我在那里写的要大得多,我绝对不会这样做。相反,我将 linq 的荣耀分成更小的块,以便更容易理解和调试。
我发现更容易看到变量赋值并自动思考:这是你必须做的设置这个值,而不是查看 ifs、else、switches 等,并尝试弄清楚它们是否是公式与否。
我认为,它可以防止开发人员在错误的地方编写不需要的副作用。
但最后,有些人可能会说它看起来很老套,或者太神秘了。
所以我提出了手头的问题:
对单个对象使用 LINQ 是否被认为是一种不好的做法?