在泛型方法中返回特定类型
本文关键字:类型 返回 泛型方法 | 更新日期: 2023-09-27 18:32:15
我写了以下方法:
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 是什么类型,并根据此处理我的变量包。当我想返回它时,我收到编译器错误。
"组件信息包类型不能隐式转换为 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
(没有任何强制转换),因为编译器已经知道package
是T
的实例。你最后的机会是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接口。
似乎您想根据传递的类型创建实例...你需要像工厂模式这样的东西。我认为你应该重新考虑你的设计