返回泛型方法中的特定类型

时间:2016-01-27 09:30:03

标签: c# generics

我写了以下方法:

public T CreatePackage<T>() where T : new()
{
        var package = new T();

        if (typeof(ComponentInformationPackage) == typeof(T))
        {
            var compInfoPackage = package as ComponentInformationPackage;

            // ...

            return compInfoPackage;
        }

        throw new System.NotImplementedException();
}

我检查 T 是什么类型,根据这个我处理我的变量。当我想要返回它时,我收到编译器错误。

&#34;类型 ComponentInformationPackage 无法隐式转换为T&#34;

我该如何解决这个问题?

5 个答案:

答案 0 :(得分:8)

首先:如果演员阵容不起作用,安全演员 工作:

return CompInfoPackage as T;

...如果class上有T约束:

public static T CreatePackage<T>() where T : class, new() { ... }

第二:鉴于此代码:

var package = new T();
if (typeof(ComponentInformationPackage) == typeof(T))
{
    var compInfoPackage = package as ComponentInformationPackage;

    // ...

    return (T)compInfoPackage; 
}

...您已经为新对象提供了引用package。由于它的类型为T,因此编译器已将其视为返回类型。为什么不回归呢?

var package = new T();
if (typeof(ComponentInformationPackage) == typeof(T))
{
    var compInfoPackage = package as ComponentInformationPackage;

    // ...

    return package; // Same object as compInfoPackage
}

答案 1 :(得分:3)

您必须转换为T,因为您的方法会返回T而不是ComponentInformationPackage的实例。

return (T)CompInfoPackage;

编译器没有机会了解T实际上是ComponentInformationPackage。但是,你已经检查过它,然后这个演员表可能永远不会失败。

但是我不确定为什么你有一个泛型类型,因为只有ComponentInformationPackage的实例由你的方法处理。省略类型参数和约束,然后简单地返回你已经做过的事情。

编辑:我已在评论中提到它,你也可以返回package(没有任何演员表),因为编译器已经知道packageT的一个实例。你有的最后一次机会是return (T)(object) CompInfoPackage,但对我来说这似乎很奇怪。

答案 2 :(得分:2)

转回T将无法按照HimBromBeere的建议运行,因此不是您的解决方案。 为了让编译器接受强制转换,您需要一个ComponentInformationPackage的附加类型约束。所以这将是你的解决方案:

public T CreatePackage<T>()
    where T : ComponentInformationPackage, new()
{
        var package = new T();

        if (typeof(ComponentInformationPackage) == typeof(T))
        {
            var compInfoPackage = package as ComponentInformationPackage;

            // ...

            return (T)compInfoPackage;
        }

        throw new System.NotImplementedException();
}

另外,我建议使用capitalization conventions作为MSDN的指南。这与你的问题无关,但这是一个提示。

答案 3 :(得分:2)

如果你想根据类型处理对象创建,你不应该在这里使用泛型(因为它不是通用的)。也许使用工厂模式来实现这一目标。

答案 4 :(得分:0)

我认为除非您的所有类型都实现了通用接口或者是一些常见的抽象类型,否则您尝试实现的内容不可能使用泛型

public T CreatePackage<T>()
    where T : IPackage, new()
{
        var package = new T();

        if (typeof(ComponentInformationPackage) == typeof(T))
        {
            var compInfoPackage = package as ComponentInformationPackage;

            // ...

            return (T)compInfoPackage;
        }

        throw new System.NotImplementedException();
}

在上面的示例中,所有类都应该实现IPackage接口

似乎你想根据传递的类型创建实例......你需要像工厂模式这样的东西。我认为你应该重新考虑你的设计