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项目模板的名称。
答案 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;
}