Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting interface type in Lazy<T>

Tags:

c#

generics

I want something like this:

public interface IAnimal
{ }

public class Dog : IAnimal
{
    public Dog() {}
}

public class Cat : IAnimal
{
    public Cat() {}
}

public abstract class TestClassBase
{
    public TestClassBase()
    {
        _lazyAnimal = CreateLazyAnimal();
    }

    private Lazy<IAnimal> _lazyAnimal = null;
    public IAnimal Animal
    {
        get
        { 
            IAnimal animal = null;
            if (_lazyAnimal != null)
                animal = _lazyAnimal.Value;

            return animal;
        }
    }

    // Could be overridden to support other animals
    public virtual Lazy<IAnimal> CreateLazyAnimal()
    {
        // default animal is a dog
        return new Lazy<Dog>(); // this type of casting doesn't work and I don't know a good workground
    }
}

I know from tinkering with MEF that it manages to find and store different types, implementing a single interface, into Lazy<T>. Just not sure how to do it myself.

like image 800
mbursill Avatar asked Dec 18 '10 18:12

mbursill


People also ask

What is Lazy T?

The Lazy<T> object ensures that all threads use the same instance of the lazily initialized object and discards the instances that are not used.

Is Lazy T thread safe?

By default, Lazy<T> objects are thread-safe. That is, if the constructor does not specify the kind of thread safety, the Lazy<T> objects it creates are thread-safe.

What does Lazy mean in C#?

Lazy initialization is a technique that defers the creation of an object until the first time it is needed. In other words, initialization of the object happens only on demand. Note that the terms lazy initialization and lazy instantiation mean the same thing—they can be used interchangeably.


1 Answers

Lazy<Dog> cannot be converted directly to Lazy<IAnimal>, but since Dog can be converted to IAnimal you can use the Lazy<IAnimal> constructor overload that expects an IAnimal (strictly speaking, it takes a Func that returns an IAnimal) and provide a Dog instead:

    public virtual Lazy<IAnimal> CreateLazyAnimal()
    {
        // default animal is a dog
        return new Lazy<IAnimal>(() => new Dog());
    }
like image 82
Bradley Grainger Avatar answered Oct 05 '22 19:10

Bradley Grainger