Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在泛型方法中返回特定类型_C#_Generics - Fatal编程技术网

C# 在泛型方法中返回特定类型

C# 在泛型方法中返回特定类型,c#,generics,C#,Generics,我编写了以下方法: public T CreatePackage<T>() where T : new() { var package = new T(); if (typeof(ComponentInformationPackage) == typeof(T)) { var compInfoPackage = package as ComponentInformationPackage;

我编写了以下方法:

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();
}
public T CreatePackage(),其中T:new()
{
var package=newt();
if(typeof(组件信息包)=typeof(T))
{
var compInfoPackage=作为组件信息包的包;
// ...
返回压缩包;
}
抛出新系统。NotImplementedException();
}
我检查T是什么类型,并根据它处理变量包。当我想要返回它时,我得到一个编译器错误

“类型ComponentInformationPackage无法隐式转换为T”


如何解决此问题?

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

return (T)CompInfoPackage;
编译器没有机会知道
T
实际上是一个
ComponentInformationPackage
。然而,正如你之前已经检查过的,这次施放可能永远不会失败

但是,我不知道为什么您有一个泛型类型,因为您的方法只处理
ComponentInformationPackage
的实例。Ommit类型param和约束,并简单地返回您已经执行的操作


编辑:我已经在注释中提到了它,您也可以返回
(不带任何强制转换),因为编译器已经知道
T
的一个实例。最后一次机会是
返回(T)(object)CompInfoPackage
,但我觉得这很奇怪。

回溯到
T
将无法按照建议工作,因此不是您的解决方案。 为了让编译器接受强制转换,您需要一个额外的类型约束
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();
}
public T CreatePackage()
其中T:ComponentInformationPackage,new()
{
var package=newt();
if(typeof(组件信息包)=typeof(T))
{
var compInfoPackage=作为组件信息包的包;
// ...
返回(T)compInfoPackage;
}
抛出新系统。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();
}
public T CreatePackage()
其中T:IPackage,new()
{
var package=newt();
if(typeof(组件信息包)=typeof(T))
{
var compInfoPackage=作为组件信息包的包;
// ...
返回(T)compInfoPackage;
}
抛出新系统。NotImplementedException();
}
在上面的示例中,所有类都应该实现IPackage接口


似乎您想要基于传递的类型创建实例……您需要类似于factory模式的东西。我认为,如果您想根据不应在此处使用泛型(因为它不是泛型)的类型处理对象创建,您应该重新考虑您的设计。也许可以使用工厂模式来实现这一点。

首先:如果强制转换不起作用,安全强制转换就起作用:

…前提是对
T
class
约束:

public static T CreatePackage<T>() where T : class, new() { ... }
…您已经有了对新对象的引用
。由于它的类型是
T
,编译器已经喜欢它作为返回类型。为什么不退回呢

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

    // ...

    return package; // Same object as compInfoPackage
}

在这种情况下,我得到一条错误消息,即类型ComponentInformationPackage无法转换为T。ComponentInformationPackage是否具有无参数构造函数?是的,并且在该方法中处理的类型更多,我只是跳过了它,以使示例代码更简单。您以前是否尝试将其强制转换为
Package
(或者只需返回
(T)包
)?这甚至不会编译。你能添加代码来显示你如何调用创建包吗?更感兴趣的是知道你在调用时传递的是什么,我猜你可能正在查看协方差规则。这不会处理OP尝试的多种类型。这可能也不会起作用,因为不是每个
T
都是这样的
组件信息包ge
。OP正在检查
T
是否是
组件信息包
,如果不是,他将抛出一个异常。关于提供的代码,最好将该约束放在那里。在这种情况下,if语句和异常也将是多余的。因此,讨论仍然是OP是否确实需要传递其他Topen泛型类型参数中的类型比
ComponentInformationPackage
多。如果您阅读了HimBromBeere answer..OP上的注释,则说明它跳过了与其他类型相关的代码types@Viru在这种情况下,问题仍然是OP想要传递给开放泛型类型参数的类型在他的问题中,除了假设他想在上下文之外做什么之外,别无选择。关于评论,这是在我键入答案时做出的。这实际上是最好的答案,因为实际上
package
compInfoPackage
是指向内存中同一对象的不同指针。第一个不是真的。type参数“T”不能与“as”运算符一起使用,因为它既没有类类型约束,也没有“class”约束。事实上,您需要对
T
进行类约束,即
其中T:class,new()
。忽略这一点很不好。另一个答案(现在看来已经不存在了)建议通过
(T)(对象)进行强制转换
--这也行,但同样,只有当
T
是引用类型时才行。@Ripple:谢谢你的提示;我已经更新了我的答案。虽然不太详细,但我认为从设计角度来看,这个答案可能是最好的。仅仅因为你可以使用泛型并不意味着你应该
var package = new T();
if (typeof(ComponentInformationPackage) == typeof(T))
{
    var compInfoPackage = package as ComponentInformationPackage;

    // ...

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

    // ...

    return package; // Same object as compInfoPackage
}