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接口。

谢谢

C# 泛型方法,不能隐式转换

您无法转换为 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; }
}