10

我有以下代码:

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

谢谢

4

4 回答 4

15

您无法转换为,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();
}
于 2012-04-07T19:30:23.180 回答
7

您的代码是非法的,因为虽然您可能正在测试并知道您给定的 T 是 BigCar 或其他类似类型,但编译器无法提前知道这一点,因此代码是非法的。根据您给定的用法,您可以

public static T GetCar<T>() where T : ICar, new()
{
    return new T();
}

new()约束允许您调用类型的默认(无参数)构造函数。

于 2012-04-07T19:31:20.450 回答
2

您可以简化代码

public static T GetCar<T>()
    where T : ICar, new()
{
    return new T();
}
于 2012-04-07T19:34:05.330 回答
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; }
}
于 2019-04-28T06:55:01.010 回答