我的应用程序使用
var results= websiteDetail.Detail.GetProductDetails<MyProduct>(code, websiteDetail.Detail.NegativeWords);
现在又调用
public List<T> GetProductDetails<T>(string websiteHtmlCode, List<string> negativeWords)
{
List<T> result = new List<T>();
foreach (var item in GetProducts(negativeWords))
{
result.Add((T)Convert.ChangeType(item, typeof(T)));
}
return result;
}
private List<MyProduct> GetProducts(List<string> negativeWords)
{
// logic
}
但是,如果我将代码更新为:
public List<T> GetProductDetails<T>(string websiteHtmlCode, List<string> negativeWords)
{
return GetProducts(negativeWords); //ERROR
}
我被告知:
无法隐式将
'System.Collections.Generic.List<MyProduct>'
类型转换为'System.Collections.Generic.List<T>
然后我更新了代码,删除List以使用单个对象,同样的问题仍然存在。
为什么当T已经是那种类型时我必须调用ListConvert.ChangeType?
答案 0 :(得分:1)
这里的问题在于理解C#泛型如何工作。
在C ++中,有一个模板专门化的概念。也就是说,你可以写:
void Foo<T> {}
void Foo<int> {}
如果T是int,它将使用专用版本,否则使用泛型。这在C#泛型中是不允许的。要么一切都是通用的,要么一切都不是。当你写
public List<T> GetProductDetails<T>(string websiteHtmlCode, List<string> negativeWords)
你现在处于泛型领域(尽管是通用方法而不是类)。因为你现在处于泛型领域,打电话给特定的函数:
List<MyProduct> GetProducts
没有任何意义。如果T是object
或String
怎么办?返回MyProduct
列表会非常混乱,并且在尝试投射时几乎肯定会失败(正如您的“工作”代码所做的那样)。换句话说,如果你总是返回一个List<MyProduct>
,为什么还要使用泛型(因此我之前的评论,它们都需要通用,或者所有具体的,你都不能混合!)。
泛型的一般规则是“T是object
”。就是这样,而且一切都可以。如果您需要比object
更多的专业化,则需要在泛型类型参数中添加where
子句。我有点怀疑你在这种情况下确实需要它,因为你看起来像是在做一个web请求。您应该只需将功能更改为:
List<T> GetProducts
此时您可能还想考虑使该类具有通用性,但这取决于您。如果您无法进行更改,我会从您的方法中删除通用性。你可以在类型oF T上进行切换,但这不是更好,并且很难理解/阅读。
通用类型约束的MSDN(where
):MSDN
如果我能说清楚的话,请告诉我!