Cannot implicitly convert derived type to its base generic type

I have the following classes and interfaces:

public interface IThing
{
    string Name { get; }
}

public class Thing : IThing
{
    public string Name { get; set; }
}

public abstract class ThingConsumer<T> where T : IThing
{
    public string Name { get; set; }
}

Now, I have a factory that will return objects derived from ThingConsumer like:

public class MyThingConsumer : ThingConsumer<Thing>
{
}

My factory currently looks like this:

public static class ThingConsumerFactory<T> where T : IThing
{
    public static ThingConsumer<T> GetThingConsumer(){
        if (typeof(T) == typeof(Thing))
        {
            return new MyThingConsumer();
        }
        else
        {
            return null;
        }
    }
}

I'm getting tripped up with this error: Error 1 Cannot implicitly convert type 'ConsoleApplication1.MyThingConsumer' to 'ConsoleApplication1.ThingConsumer<T>'

Anyone know how to accomplish what I'm attempting here?

Thanks!

Chris

Answers


If you make ThingConsumer<T> an interface rather than an abstract class, then your code will work as is.

public interface IThingConsumer<T> where T : IThing
{
    string Name { get; set; }
}

Edit

One more change needed. In ThingConsumerFactory, cast back to the return type IThingConsumer<T>:

return (IThingConsumer<T>)new MyThingConsumer();

The compiler is stumbling over the conversion from MyThingConsumer to ThingConsumer<T> even though T:IThing and MyThingConsumer:Thingconsumer<Thing> and Thing:IThing. Which is quite a few hoops for it to jump through!

The code works if you use return new MyThingConsumer() as ThingConsumer<T>; instead of a direct cast. You know the result will never be null, and the compiler is happy because it is guaranteed a return value of the right type at runtime.

Edit: Here is the full code I used for testing (in Snippy):

public interface IThing
{
    string Name { get; }
}

public class Thing : IThing
{
    public string Name { get; set; }
}

public abstract class ThingConsumer<T> where T : IThing
{
    public string Name { get; set; }
}

public class MyThingConsumer : ThingConsumer<Thing>
{
}

public static class ThingConsumerFactory<T> where T : IThing
{
    public static ThingConsumer<T> GetThingConsumer()
    {
        if (typeof(T) == typeof(Thing))
        {
            return new MyThingConsumer() as ThingConsumer<T>;
        }
        else
        {
            return null;
        }
    }
}

...

var thing = ThingConsumerFactory<Thing>.GetThingConsumer();
Console.WriteLine(thing);

You need to define your class like this I believe:

public class MyThingConsumer<Thing> : ThingConsumer

The reason is that ThingConsumer is already typed in its definition with this: where T : IThing

Now, you can make the call return new MyThingConsumer<T>();.

This should in turn match the expected return type of ThingConsumer<T>

EDIT

Sorry for the confusion, here is what should work:

public class MyThingConsumer<T> : ThingConsumer<T> where T : IThing

and

return new MyThingConsumer<T>();

Need Your Help

How to get an HTML element's style values in javascript?

javascript html css stylesheet

I am looking for a way to retrieve the style from an element that has a style set upon it by the style tag.