virtual
方法。它有一个返回类型
IEnumerable<Uri>
。如果枚举,基类不会
yield
任何结果,但派生类可以选择重写该方法并返回所需数量的项目。这是基本方法:
public virtual IEnumerable<Uri> GetBaseAddresses() { }
问题是,它无法编译。您
必须返回一个值,编译器才会满意。所以,因为我想要一个空结果,所以我就返回 null
,对吧?
public virtual IEnumerable<Uri> GetBaseAddresses() { return null; }
问题在于,如果有人对基类的实例执行
foreach
,他们将会崩溃,并出现“对象引用未设置...”的运行时错误所以,回想一下
yield return
关键字对 C# 编译器有一些魔力……我想出了这个编译器 hack(顺便说一下,它可以工作)。
public virtual IEnumerable<Uri> GetBaseAddresses()
{
if (false) { yield return new Uri(""); }
}
奇怪的是,即使“if (false) { ... }”代码被完全编译掉 - 编译器对我满足“必须返回一个值”的要求感到满意,并且完全按照我想要的进行 - 也就是说,可以安全枚举的空结果集。
我的问题是 - 有没有办法在没有我的编译器技巧的情况下做到这一点?
yield break; //end enumeration
从评论中提取 svick 的想法:
return Enumerable.Empty<Uri>();
这更快,因为
Enumerable.Empty
总是返回一些空枚举的缓存的、预先分配的实例。
public virtual IEnumerable<Uri> GetBaseAddresses()
{
return Enumerable.Empty<Uri>();
}
或者如果您的目标是 .NET 框架的某个版本
< 3.5 return an empty List.
public virtual IEnumerable<Uri> GetBaseAddresses()
{
return new Uri[0];
}
yield
关键字,那么您想要创建一个普通方法,而不是迭代器。这也是你的
if (false)
hack 起作用的原因。要正确编写返回空集合的方法,您可以按照通常的方式返回空集合:
public virtual IEnumerable<Uri> GetBaseAddresses()
{
return Enumerable.Empty<Uri>();
}
或者你可以使用
yield break
:
public virtual IEnumerable<Uri> GetBaseAddresses()
{
yield break;
}