2017-12-27 358 views
1

我正在试验C#7的新功能,尤其是本地方法。我写了Linq Where Operator。在C#7本地方法中重新引入新的通用参数是否是一种好的做法?

我实现了迭代器块作为本地方法(事实上,我阅读文章说本地方法是异步方法和迭代器的完美解决方案)。

我想知道这两个实现是否有区别,如果不是哪一个最好?

先执行:

这里我引入了新的泛型类型参数的本地方法,新名称为参数...

public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if(source == null) throw new ArgumentNullException(nameof(source)); 
    if(predicate == null) throw new ArgumentNullException(nameof(predicate)); 
    return WhereIterator(source, predicate); 

    IEnumerable<TSequence> WhereIterator<TSequence> (IEnumerable<TSequence> localSource, Func<TSequence, bool> localPredicat) { 
     foreach(TSequence item in localSource) { 
      if(localPredicat(item)) { 
       yield return item; 
      } 
     } 
    } 
} 

第二个执行:

没有新的通用参数,没有新的p因为本地方法可以捕获封闭方法的变量。

public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if(source == null) throw new ArgumentNullException(nameof(source)); 
    if(predicate == null) throw new ArgumentNullException(nameof(predicate)); 
    return WhereIterator(); 

    IEnumerable<TSource> WhereIterator() { 
     foreach(TSource item in source) { 
      if(predicate(item)) 
       yield return item; 
      } 
     } 
    } 
} 
+2

我不明白为什么你甚至需要一个WhereIterator。你可能没有它,并在Where方法中进行foreach。 – rokkerboci

+0

你可以检查反编译源代码[here](https://sharplab.io)。只需将这些函数编写并在右侧窗口中查看结果。 –

+0

我需要激烈的参数验证:),如果我不使用WhereIterator方法,参数验证是懒惰地完成的。 这就是为什么我实现了迭代器作为本地方法。 –

回答

2

你的第二个实施更好。主要的区别是,第二执行隐含捕获它的参数,从重复自己释放你:

指定参数类型时
  • 时指定参数名称,并
  • 传递参数的功能时。

避免重复是一个非常重要的编程习惯,所以你应该更喜欢你的第二个实现。

+1

@IvanStoev你是对的,这是非常有道理的。感谢您的评论! – dasblinkenlight

+0

确切地说,我们需要激烈的参数验证。这是我首先使用本地方法的主要原因。 在我使用私有静态方法实现迭代器块之前,现在我们已经有了本地方法,所以它更好,因为它有助于保持将实现Linq扩展方法的类从迭代器块中清除。 简而言之,它帮助我将迭代器块从类中移动到Linq运算符方法,因为它仅在该方法内使用。 –

+0

但现在我很困惑。我的问题很简单:我们是否应该使用实现迭代器块来使用本地方法可以捕获封闭方法的外部变量的事实,还是应该忽略它并引入新的参数类型和参数? –

相关问题