无法隐式转换类型';System.Collections.Generic.List<;我的产品>';

本文关键字:lt List 我的 gt Generic System 转换 类型 Collections | 更新日期: 2023-09-27 17:58:45

我的应用程序使用

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类型时,为什么我必须调用它?

无法隐式转换类型';System.Collections.Generic.List<;我的产品>';

这里的问题在于理解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是objectString呢?返回MyProduct的列表将非常令人困惑,并且在尝试强制转换时几乎肯定会失败(就像您的"工作"代码所做的那样)。换句话说,如果你总是返回一个List<MyProduct>,为什么要使用泛型呢(因此,我之前的评论是,它们需要都是泛型的,或者都是具体的,你不能混合!)。

泛型的一般规则是"T是object"。如果您需要比object更多的专业化,则需要在泛型类型参数中添加where子句。我有点怀疑你在这种情况下是否真的需要,因为你看起来只是在做一个网络请求。您应该能够将您的功能更改为:

List<T> GetProducts

在这一点上,您可能还想考虑将类设为泛型,但这取决于您。如果你不能做出改变,我会从你的方法中删除泛型。你可以在oF T类型上切换,但这并没有更好,而且很难理解/阅读。

MSDN通用类型约束(where):MSDN

如果我能澄清什么,请告诉我!