包含 foreach 语句的方法只有一个返回值

Posted

技术标签:

【中文标题】包含 foreach 语句的方法只有一个返回值【英文标题】:Method containing foreach statment to have only one return 【发布时间】:2015-10-21 14:58:18 【问题描述】:

我为单元测试准备了以下方法,我知道它总是会运行 for-each 循环,有没有办法摆脱第二个 return 语句?

public Enums.GYRStatus GetStatusForTransformer(
            string factoryCode, 
            Enums.Technology technology, 
            string transformerType,
            int transformerSize,
            string transformerModel)

   fakeStandardsAndSizesFictionary = new Dictionary<Tuple<string,
                                                    Enums.Technology,
                                                    string, int, string>, int>() 
   
        Tuple.Create("SELUD", Technology.CVT,"---", 0, ""), 1 ;
   

   foreach (var pair in fakeStandardsAndSizesFictionary)
   
       if (pair.Key.Item1 == factoryCode &&
          pair.Key.Item2 == technology &&
          pair.Key.Item3 == transformerType &&
          pair.Key.Item4 == transformerSize &&
          pair.Key.Item5 == transformerModel)
           return (Enums.GYRStatus)pair.Value;
   
   return (Enums.GYRStatus)1; // second return never used

【问题讨论】:

【参考方案1】:

你可以替换

return (Enums.GYRStatus)1;

throw new InvalidOperationException();

假设永远不应该到达这个地方,它在语义上看起来也更正确。

【讨论】:

抱歉 :o 没有注意到我的编辑删除了最后一条语句...我现在感觉很糟糕 :c @MischaBehrend 完全没问题,我接受了编辑并重新添加了句子。谢谢!【参考方案2】:

你可以这样做:

public Enums.GYRStatus GetStatusForTransformer(string factoryCode,   Enums.Technology technology, string transformerType, int transformerSize, string transformerModel)

    fakeStandardsAndSizesFictionary = new Dictionary<Tuple<string, Enums.Technology, string, int, string>, int>() 
    
        Tuple.Create("SELUD",Technology.CVT,"---",0 ,""),1,
    ;

    return fakeStandardsAndSizesFictionary
        .Where(pair =>
            pair.Key.Item1 == factoryCode
                && pair.Key.Item2 == technology
                && pair.Key.Item3 == transformerType
                && pair.Key.Item4 == transformerSize
                && pair.Key.Item5 == transformerModel)
        .Select(pair => (Enums.GYRStatus)pair.Value)
        .First();

【讨论】:

【参考方案3】:

假设(GYRStatus)1 是一个有效的返回值,你可以这样做:

GYRStatus status = GYRStatus.First;
foreach (var pair in fakeStandardsAndSizesFictionary)

   if (pair.Key.Item1 == factoryCode &&
   pair.Key.Item2 == technology &&
   pair.Key.Item3 == transformerType &&
   pair.Key.Item4 == transformerSize &&
   pair.Key.Item5 == transformerModel)
   
      status = (Enums.GYRStatus)pair.Value;
      break;
   

return status;

您还可以返回 GYRStatus? 以指示未选择任何值:

GYRStatus? status = null;
foreach (var pair in fakeStandardsAndSizesFictionary)

   if (pair.Key.Item1 == factoryCode &&
   pair.Key.Item2 == technology &&
   pair.Key.Item3 == transformerType &&
   pair.Key.Item4 == transformerSize &&
   pair.Key.Item5 == transformerModel)
   
      status = (Enums.GYRStatus)pair.Value;
      break;
   

return status;

或者,您的枚举中也可以有一个GYRStatus.None 值。这一切都取决于执行流程。如果您最终可能找不到谓词的值,请返回默认值而不是抛出异常。如果不可能,扔掉。

【讨论】:

【参考方案4】:

没有,即使你知道它总是会返回,编译器也不会!

【讨论】:

【参考方案5】:

编译器无法知道循环总是返回一个值。因此,您还必须提供该开关。

【讨论】:

【参考方案6】:
public Enums.GYRStatus GetStatusForTransformer(
            string factoryCode, 
            Enums.Technology technology, 
            string transformerType,
            int transformerSize,
            string transformerModel)

   Enums.GYRStatus retValue=(Enums.GYRStatus)1;
   fakeStandardsAndSizesFictionary = new Dictionary<Tuple<string,
                                                    Enums.Technology,
                                                    string, int, string>, int>() 
   
        Tuple.Create("SELUD", Technology.CVT,"---", 0, ""), 1 ;
   

   foreach (var pair in fakeStandardsAndSizesFictionary)
   
       if (pair.Key.Item1 == factoryCode &&
          pair.Key.Item2 == technology &&
          pair.Key.Item3 == transformerType &&
          pair.Key.Item4 == transformerSize &&
          pair.Key.Item5 == transformerModel)
           retValue = (Enums.GYRStatus)pair.Value;
   
   return retValue; 

【讨论】:

以上是关于包含 foreach 语句的方法只有一个返回值的主要内容,如果未能解决你的问题,请参考以下文章

C# 使用IEnumerable,yield 返回结果,同时使用foreach时,在循环内修改变量的值无效

如何获取 linq `ForEach` 语句以返回有关为每个列表对象进行的方法调用的数据?

当方法包含多个具有多个返回的 if 语句时,如何从方法中获取返回值?

数组的forEach和map和for方法的区别

在 foreach 中调用类仅最后一次调用有效

如何从 Parallel.ForEach 收集返回值?