Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C应该有forone结构吗?(或者,处理零或一个案例的最干净方式是什么)_C#_Ienumerable_Language Features - Fatal编程技术网

C# C应该有forone结构吗?(或者,处理零或一个案例的最干净方式是什么)

C# C应该有forone结构吗?(或者,处理零或一个案例的最干净方式是什么),c#,ienumerable,language-features,C#,Ienumerable,Language Features,当处理一个枚举包含一个或多个不包含的项时,foreach循环可以很容易地对它们进行迭代,而LINQ Select可以很容易地从枚举中投影项 foreach (var attr in p.GetCustomAttributes().OfType<A>()) ... 您可以事先添加一个检查,以确保只有一个代码契约需要检查,或者添加一个新的代码契约,但这相当混乱: Contract.Requires(p..GetCustomAttributes().OfT

当处理一个枚举包含一个或多个不包含的项时,foreach循环可以很容易地对它们进行迭代,而LINQ Select可以很容易地从枚举中投影项

        foreach (var attr in p.GetCustomAttributes().OfType<A>()) ...
您可以事先添加一个检查,以确保只有一个代码契约需要检查,或者添加一个新的代码契约,但这相当混乱:

        Contract.Requires(p..GetCustomAttributes().OfType<A>().Count() < 2);
        foreach (var attr in p.GetCustomAttributes().OfType<A>()) ...
或者,您可以摆脱循环,使用.SingleOrDefault,然后测试null,这显然是最清楚的意图,并确保循环执行零次或一次,但它更多的是代码,更少的“声明性”和不“可组合性”:

            var attr =  p.GetCustomAttributes().OfType<A>().SingleOrDefault();
            if (attr != null)
            {
               ...
那么问题是:人们更喜欢上述哪一个或其他建议?为什么?大多数习惯于过程代码的程序员自然会更喜欢if语句,但是对于那些深谙函数式编程的人来说,你有更好的方法吗

其他一些语言有干净的技术来处理这个问题,例如,F的数组模式可以匹配零、一或多个,或者失败。在C语言中,是否有一个forone构造相当于检查枚举中是否有零或一,然后执行它的情况

[这里的具体示例是获取自定义属性,其中属性已标记为不允许多个,但问题更一般地是如何处理零/一情况。]

显然,我将选择SingleOrDefault,因为:

1这是一种内置方法。我不需要自己编写额外的方法。泽洛龙先生,你出局了

2一个简单的例子:

 var attr =  source.SingleOrDefault();
 if (attr != null)
 {
   //do something to attr
 }
 else
 {
   //the source is empty
   //throw an exception or prompt the user or something equivalent
 }
如果使用其他解决方案,恐怕需要编写另一个If语句来检查source.Count。所以SingleOrDefault是赢家。

显然我会选择SingleOrDefault,因为:

1这是一种内置方法。我不需要自己编写额外的方法。泽洛龙先生,你出局了

2一个简单的例子:

 var attr =  source.SingleOrDefault();
 if (attr != null)
 {
   //do something to attr
 }
 else
 {
   //the source is empty
   //throw an exception or prompt the user or something equivalent
 }
如果使用其他解决方案,恐怕需要编写另一个If语句来检查source.Count。所以SingleOrDefault是赢家。

编辑:

有了这个澄清,我更倾向于在循环中使用ZeroOrOne扩展方法。它基本上会做你在一个以上的显式测试中所做的事情。我有点纠结于它应该返回IEnumerable还是null。我想这取决于你通常如何使用结果

旧答案

在我看来,您想要的是扩展方法,而不是.SingleOrDefault

你说:

您可以添加.Take1,以明确您最多只需要一个,并确保循环只执行一次。但如果存在多个异常,则不会引发异常

        foreach (var attr in ...().Take(1)) ...
你所描述的是单身。另外,它很短,非常清楚地表明了你的意图

var attr = p.GetCustomAttributes().OfType<A>().Single();
// will throw exception if there is more than one attribute of type A
编辑:

有了这个澄清,我更倾向于在循环中使用ZeroOrOne扩展方法。它基本上会做你在一个以上的显式测试中所做的事情。我有点纠结于它应该返回IEnumerable还是null。我想这取决于你通常如何使用结果

旧答案

在我看来,您想要的是扩展方法,而不是.SingleOrDefault

你说:

您可以添加.Take1,以明确您最多只需要一个,并确保循环只执行一次。但如果存在多个异常,则不会引发异常

        foreach (var attr in ...().Take(1)) ...
你所描述的是单身。另外,它很短,非常清楚地表明了你的意图

var attr = p.GetCustomAttributes().OfType<A>().Single();
// will throw exception if there is more than one attribute of type A

此外,SingleOrDefault可确保顶部只有一个项目。就像它选择SQL中的Top2一样,它确保只返回一个项。SingleOrDefault也确保只返回一个tops项。就像它选择SQL中的Top2一样,它确保只返回一个项。不,Single得到一个或一个异常。在这种情况下,我们想要零或一,但不要更多;我更喜欢Zerorone。不,单身可以得到一个或一个例外。在这种情况下,我们想要零或一,但不要更多;我更喜欢Zerorone。