繁体   English   中英

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

[英]Return specific type in generic method

我写了以下方法:

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是什么类型,根据这个我对待我的变量 当我想要返回它时,我得到编译器错误。

ComponentInformationPackage类型不能隐式转换为T”

我怎么解决这个问题?

第一:如果演员不起作用,安全演员阵容确实有效:

return CompInfoPackage as T;

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

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
}

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

return (T)CompInfoPackage;

编译器没有机会知道T实际上是一个ComponentInformationPackage 但是,由于您已经在此演员表之前检查了它,因

但是我不确定为什么你有一个泛型类型,因为只有ComponentInformationPackage实例由你的方法处理。 省略类型参数和约束,并简单地返回您已经执行的操作。

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

回归到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();
}

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM