在泛型方法中从泛型类型转换为另一种类型

时间:2016-11-16 14:31:26

标签: c#

使用关键字dynamic在此方法中工作,如此处所示,但我试图找出一种方法,不使用动态或var。我想使用通用方法。我可以使用任何模式或转换实用程序吗?

public static TAngle AngleBetween<TAngle>(Vector vector1, Vector vector2) where TAngle : IAngle
{
    dynamic radians = (Radian)AngleBetween(vector1, vector2);

    return (TAngle)radians;
}

这给出了期望的结果,但它违反了Liskov原则:

    public static TAngle AngleBetween<TAngle>(Vector vector1, Vector vector2) where TAngle : IAngle
    {
        double result = AngleBetween(vector1, vector2);

        Radian              resultRadian = new Radian(result);

    Degree              testDegree   = new Degree();
        DegreeMinuteSecond  testDMS      = new DegreeMinuteSecond();
        Gradian             testGradian  = new Gradian();
        Turn                testTurn     = new Turn();

        if (typeof(TAngle) == typeof(Degree))
        {
            testDegree = (Degree)resultRadian;
            return (TAngle)(object)testDegree;
        }
        else if (typeof(TAngle) == typeof(DegreeMinuteSecond))
        {
            testDMS = (DegreeMinuteSecond)resultRadian;
            return (TAngle)(object)testDMS;
        }

        else if (typeof(TAngle) == typeof(Gradian))
        {
            testGradian = (Gradian)resultRadian;
            return (TAngle)(object)testGradian;
        }

        else if (typeof(TAngle) == typeof(Turn))
        {
            testTurn = (Turn)resultRadian;
            return (TAngle)(object)testTurn;
        }

        else return (TAngle)(object)resultRadian;

    }

有没有人有任何建议?

1 个答案:

答案 0 :(得分:4)

编译器无法保证这一切都会成功:

TAngle radians = (Radian)AngleBetween(vector1, vector2);

毕竟,如果TAngle而不是 a Radian,该怎么办?对它的约束是:

where TAngle : IAngle

但是没有编译时保证Radian是唯一能够实现IAngle的东西。

因此错误。

但更重要的是,考虑到这种方法的实施,它首先不应该是通用的。由于始终想要返回Radian,只需返回Radian

public static Radian AngleBetween(Vector vector1, Vector vector2)
{
    Radian radians = (Radian)AngleBetween(vector1, vector2);

    return radians;
}

或者,如果您想要返回IAngle,那也会有效:

public static IAngle AngleBetween(Vector vector1, Vector vector2)
{
    IAngle radians = (Radian)AngleBetween(vector1, vector2);

    return radians;
}

如果某些东西可能有多种类型,泛型很有用,但这种实现方式通过强制转换,坚持使用一种特定的类型。