6

我有一部分代码我真的不喜欢,如果有可能以某种方式简化它 - 会非常好。

A a; // I want to get rid of this variable
if((a = collection.FirstOrDefault(x => x.Field == null)) != null)
{
  throw new ScriptException("{0}", a.y); //I need to access other field of the object here, that's why I had to declare a variable outside of the expression
}
4

7 回答 7

7

如果您将变量赋值和定义结合起来,您可以使您的代码更具可读性:

A a = collection.FirstOrDefault(x => x.Field == null);

if(a != null)    
   throw new ScriptException("{0}", a.y);
于 2013-10-23T15:21:27.850 回答
7

与其查找第一个匹配项并对其进行处理,不如将结果视为一个集合。 foreach在所有匹配的项目上使用Where. 由于异常将使您退出循环,因此最终结果是相同的,只是代码更简洁:

foreach(var a in collection.Where(x => x.Field == null))
    throw new ScriptException("{0}", a.y);

如果您想让读者更清楚循环最多只执行一次,您可以在其中添加一个Take调用来澄清代码而不进行任何功能更改:

foreach(var a in collection.Where(x => x.Field == null).Take(1))
    throw new ScriptException("{0}", a.y);

这也使得聚合所有无效项变得更容易,而不是第一个:

var exceptions = collection.Where(a => a.Field == null)
    .Select(a => new ScriptException("{0}", a.y))
    .ToList();
if (exceptions.Any())
    throw new AggregateException(exceptions);
于 2013-10-23T15:21:31.280 回答
2

您无法避免声明变量,因为您需要在外部分配if然后引用内部的值。(唯一的方法是执行两次过滤,这可能很昂贵)。

也就是说,您可以利用这一点并使代码更具可读性:

A a = collection.FirstOrDefault(x => x.Field == null); // assign here
if(a != null) // more easily-readable comparison here
{
  throw new ScriptException("{0}", a.y); 
}
于 2013-10-23T15:23:08.800 回答
1

A a在这种情况下你无法摆脱。您需要存储从 LINQ 语句返回的值以供以后使用,并且与using块不同,if语句不允许您在其表达式中定义变量。

就个人而言,我会这样做:

A a = collection.FirstOrDefault(x => x.Field == null);
if(a != null)
{
    throw new ScriptException("{0}", a.y);
}
于 2013-10-23T15:21:48.767 回答
1

所以你的逻辑是:如果有任何项目没有字段,则抛出异常。

var a = collection.Where(x => x.Field == null);
if(a.Any())
{
  throw new ScriptException("{0}", a.First().y);
}

更好的方法可能是整理它们:

var a = collection.Where(x => x.Field == null).Select(x => x.y);
if(a.Any())
{
  throw new ScriptException("{0}", string.Join(',', a));
}

这样你就可以看到所有的实例。

于 2013-10-23T15:29:08.107 回答
0

这对你有用吗?它很难看,但你可以在 lambda 中抛出异常。

collection.FirstOrDefault(x => { 
                                 if(x.Field == null)
                                 {
                                       throw new ScriptException("{0}", x.y);
                                 }
                                 return false;
                                }
                          );
于 2013-10-23T15:37:42.233 回答
0

您可以使用 a.Select删除对 的外部引用a,尽管结果仍然有点混乱:

collection.Where(x => x.Field == null)
    .Select(a => string.Format("{0}", a.y))
    .Take(1).ToList().ForEach(msg => 
        throw new ScriptException(msg);
    );

Take(1)如果没有匹配的项目,则返回一个空的可枚举,因此块 inForEach将运行零次或一次。

于 2013-10-23T15:23:18.473 回答