我有以下代码:
public static T GetCar<T>() where T : ICar
{
T objCar = default(T);
if (typeof(T) == typeof(SmallCar)) {
objCar = new SmallCar("");
} else if (typeof(T) == typeof(MediumCar)) {
objCar = new MediumCar("");
} else if (typeof(T) == typeof(BigCar)) {
objCar = new BigCar("");
}
return objCar;
}
这是我得到的错误:Cannot implicitly convert type 'Test.Cars' to 'T'
我在这里错过了什么?所有汽车类型都实现了ICar界面。
由于
答案 0 :(得分:9)
由于T在编译时未知,因此无法转换为T
。
如果您希望让代码生效,可以将返回类型更改为ICar
并删除通用T
返回类型。
您也可以转发T
。这也会奏效。
如果您只使用默认构造函数,则还可以在new()
上使用new T()
并使用public ICar GetCar<T>()
where T : ICar
{
ICar objCar = null;
if (typeof(T) == typeof(SmallCar)) {
objCar = new SmallCar();
} else if (typeof(T) == typeof(MediumCar)) {
objCar = new MediumCar();
} else if (typeof(T) == typeof(BigCar)) {
objCar = new BigCar();
}
return objCar;
}
来使代码生效。
public T GetCar<T>()
where T : ICar
{
Object objCar = null;
if (typeof(T) == typeof(SmallCar)) {
objCar = new SmallCar();
} else if (typeof(T) == typeof(MediumCar)) {
objCar = new MediumCar();
} else if (typeof(T) == typeof(BigCar)) {
objCar = new BigCar();
}
return (T)objCar;
}
角色:
public T GetCar<T>()
where T : ICar, new()
{
return new T();
}
新约束:
{{1}}
答案 1 :(得分:7)
您的代码是非法的,因为虽然您可能正在测试并知道您的给定T是BigCar或其他类型,但编译器无法提前知道,因此代码是非法的。根据您的用途,您可以
public static T GetCar<T>() where T : ICar, new()
{
return new T();
}
new()
约束允许您在类型上调用默认(无参数)构造函数。
答案 2 :(得分:2)
您可以简化代码
public static T GetCar<T>()
where T : ICar, new()
{
return new T();
}
答案 3 :(得分:0)
泛型是一个运行时概念。通用数据类型中使用的类型信息,无论其值或引用类型是否可以在运行时使用反射获取。
将带有T的代码编译到MSIL中时,它仅将其标识为具有类型参数。因此,泛型参数T在编译时未知。
class Program
{
static void Main(string[] args)
{
ICar smallCar = Helper.GetCar<SmallCar>("car 1");
ICar mediumCar = Helper.GetCar<MediumCar>("car 2");
Console.ReadLine();
}
}
static class Helper
{
public static T GetCar<T>(string carName) where T : ICar
{
ICar objCar = default(T);
if (typeof(T) == typeof(SmallCar))
{
objCar = new SmallCar { CarName = carName };
}
else if (typeof(T) == typeof(MediumCar))
{
objCar = new MediumCar { CarName = carName };
}
return (T)objCar;
}
}
interface ICar
{
string CarName { get; set; }
}
class SmallCar : ICar
{
public string CarName { get; set ; }
}
class MediumCar : ICar
{
public string CarName { get; set; }
}