Search code examples
c#ienumerablevirtualyield-return

Virtual IEnumerable<T> that compiles empty


I am making a base class that has a virtual method called "GetBaseAddresses()". It has as a return type IEnumerable<Uri>. The base class will not yield any results if enumerated, but a derived class has the option to override the method and return as many items as it wants.

Here is the base method:

public virtual IEnumerable<Uri> GetBaseAddresses() { }

The problem is, that won't compile. You must return a value for the compiler to be happy. So, because I want to have an empty result, I would just return null, right?

public virtual IEnumerable<Uri> GetBaseAddresses() { return null; }

The problem there is that if someone does a foreach on an instance of the base class, they will crash with a runtime error of "Object reference not set..."

So, recalling that the yield return keyword does some magic with the C# compiler... I came up with this compiler hack (that works by the way).

public virtual IEnumerable<Uri> GetBaseAddresses()
{
    if (false) { yield return new Uri(""); }
}

Strangely enough, even though the "if (false) { ... }" code gets completely compiled away - the compiler is happy with me meeting the "must return a value" requirement, and does exactly what I want - that is, an empty result set that is safe to enumerate.

My question is - Is there a way to do this without my compiler trick?


Solution

  • Just return an empty enumerable in the base method.

        public virtual IEnumerable<Uri> GetBaseAddresses()
        {
            return Enumerable.Empty<Uri>();
        }
    

    Or if you're targeting a version of the .NET framework < 3.5 return an empty List.