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
}