泛型不能转换类型

时间:2015-03-23 15:58:38

标签: c# .net generics sitecore

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;
 }

我在创建派生类型的实例时遇到了这些构建错误:

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

编辑:itemTemplate参数是Sitecore项目模板的名称。

2 个答案:

答案 0 :(得分:9)

你需要转换为T - 但首先,有点烦人的是,你需要转换为object,因为转换规则要在C#中输入参数。

我个人会删除局部变量,但这对你没有帮助:

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");
     }
}

你应该考虑一下通用方法是否合适......你是否真的在使方法返回IComponent并让调用者进行投射时获得了什么?

基本上,不清楚条件与所要求的类型有什么关系。

答案 1 :(得分:4)

C#编译器阻止的原因是你可以调用:

GetComponent<A>("condition_2");

此调用不会满足编译器,因为“condition_2”将创建新的B,而不是A。

由于您只使用Generic类型T作为返回类型,我建议您不要在此处使用Generic,只需遵循工厂模式:

private static IComponent GetComponent(string condition)
{
    IComponent component;
    switch (condition)
    {
        case "condition_1":
            component = new A();
            break;
        case "condition_2":
            component = new B();
            break;
        case "condition_3":
            component = new C();
            break;
        default:
            throw new ArgumentOutOfRangeException("condition");
    }
    return component;
}