C# 泛型方法,不能隐式转换
本文关键字:转换 不能 泛型方法 | 更新日期: 2023-09-27 18:30:17
我有以下代码:
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接口。
谢谢
您无法转换为 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();
}
你的代码是非法的,因为虽然你可能正在测试并且知道你给定的T是BigCar或其他类似类型,但编译器无法提前知道,因此代码是非法的。根据您的给定使用情况,您可以拥有
public static T GetCar<T>() where T : ICar, new()
{
return new T();
}
new()
约束允许您在类型上调用默认(无参数)构造函数。
您可以简化代码
public static T GetCar<T>()
where T : ICar, new()
{
return new T();
}
泛
型是一个运行时概念。泛型数据类型中使用的类型的信息,无论它是值还是引用类型,都可以在运行时使用反射获取。
当带有 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; }
}