mso*_*hie 3 .net c# extension-methods .net-3.5
我不能做我想做的事.我只想要非国际代表的账户.但是当我调用ActiveAccounts()时,我没有得到null,我得到一个可枚举的,然后包含null.我在这做错了什么?请帮忙.
public static class AccountExt
{
public static IEnumerable<Account> ActiveAccounts( this AccountRep rep )
{
if( rep == null )
throw new ArgumentNullException();
if( rep.IsInternational )
yield return null;
foreach( var acc in rep.FetchAccounts() )
{
if( acc.IsActive )
yield return acc;
}
}
}
Run Code Online (Sandbox Code Playgroud)
嗯,这里有几件事情.
首先,你不只是有一个扩展方法,你有一个扩展方法 迭代器块 - 这是你yield return用来自动实现IEnumerable<>合同时得到的.
听起来你想要发生的是ActiveAccounts()返回null IEnumerable<Account>.实际发生的是,对于国际代表,您将返回null 作为IEnumerable的第一个元素.我怀疑你可能试过return null在那里使用,但有一个编译器错误,如:
错误:无法从迭代器返回值.使用yield return语句返回一个值,或者使用yield break来结束迭代.
如果你想要的是可枚举的空是什么,你想要的yield break不是yield return null.通常,返回空序列实际上是一个更好的主意,因为它允许调用者避免检查返回值.它还使用LINQ等技术更好地运行,LINQ使用组合来组合复杂的查询.
第二个问题是,在if( rep == null )调用时不会评估前置条件ActiveAccounts(),而是在您开始枚举该调用的结果时.这可能不是你想要的 - 我想你想要立即评估前提条件.
解决这两个问题的方法是使用两阶段实现:
public static class AccountExt
{
// apply preconditions, return null for international reps
public static IEnumerable<Account> ActiveAccounts( this AccountRep rep )
{
if( rep == null )
throw new ArgumentNullException( "rep" );
if( rep.IsInternational )
return null;
// otherwise...
return ActiveAccountsImpl( rep );
}
// private implementation handles returning active accounts
private static IEnumerable<Account> ActiveAccountsImpl( AccountRep rep )
{
foreach( acc in rep.FetchAccounts() )
{
if( acc.IsActive )
yield return acc;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您愿意使用LINQ,可以避免使用Impl该函数的版本:
public static IEnumerable<Account> ActiveAccounts( this AccountRep rep )
{
if( rep == null )
throw new ArgumentNullException( "rep" );
if( rep.IsInternational )
return null;
// otherwise, using LINQ to filter the accounts...
return rep.FetchAccounts().Where( acc => acc.IsActive );
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处了解有关迭代器如何阻止的更多信息.
此时应更换yield return null使用yield break.这将返回一个空序列.
如果你真的想要返回null而不是IEnumerable当时LBushkin的答案是你想要的那个; 但是,更常见的做法是返回一个空序列,因为它不需要消费者必须检查返回值.
| 归档时间: |
|
| 查看次数: |
1986 次 |
| 最近记录: |