Generics cannot convert type

interface IComponent { /*code*/ }
interface IContent : IComponent { /*code*/ }
interface IMedia : IComponent { /*code*/ }
class A : IContent { /*code*/ }
class B : IMedia { /*code*/ }
class C : IContent, IMedia { /*code*/ }

private static T GetComponent<T>(string itemTemplate)
        where T : IComponent, new ()
{
    T component;
    switch (itemTemplate)
    {
        case "template_1":
            component = new A();
            break;
        case "template_2":
            component = new B();
            break;
        case "template_3":
            component = new C();
            break;
        default:
            throw new ArgumentOutOfRangeException("itemTemplate");
     }
     return component;
 }

I am getting these build errors where I'm creating instances of the derived types:

Cannot implicitly convert type 'Objects.A' to 'T'
Cannot implicitly convert type 'Objects.B' to 'T'
Cannot implicitly convert type 'Objects.C' to 'T'

EDIT: The itemTemplate parameter is the name of the template of a Sitecore Item.

Jon Skeet
people
quotationmark

You need to cast to T - but first, somewhat annoyingly, you need to cast to object due to the rules around conversions to type parameters in C#.

I would personally get rid of the local variable though, which isn't helping you:

private static T GetComponent<T>(string condition)
        where T : IComponent, new ()
{
    switch (condition)
    {
        case "condition_1":
            return (T) (object) new A();
        case "condition_2":
            return (T) (object) new B();
        case "condition_3":
            return (T) (object) new C();
        default:
            throw new ArgumentException("condition");
     }
}

You should really consider whether a generic method is appropriate here though... are you actually gaining anything over making the method return IComponent and letting the caller cast?

Basically, it's unclear what relation the condition has to the type being requested.

people

See more on this question at Stackoverflow