C#泛型方法的值

3

我需要编写一个方法,用于在List中返回泛型类的子元素。我写了以下代码:

static List<Model<T>> Get<T>( string value ) where T : Model<T>
{
    switch( value )
    {
        case "ROLE":
        return GetRoles();
    }
    return new List<Model<T>>();
}

GetRoles() 返回 List<Role>,其中 Role : Model<Role>
但是 Visual Studio 告诉我它无法将 List<Role> 转换为 List<Model<T>>


供以后参考,这是一个通用方法而不是一个模板函数。C++ 模板和 C# 泛型类似但并不相同-请参阅 https://msdn.microsoft.com/zh-cn/library/c6cyy67b.aspx - Jon Davies
类也是泛型的吗? - A. Akzhigitov
是的,无论何时在C#中看到<...>,它都是泛型而不是模板 - Jon Davies
2个回答

3
这里的错误在于,List<Role>List<Model<T>>并不相同,即使Role是一个Model<Role>
例如,你有两个类:
public class Bar : Model<Foo>
{

}

public class Foo : Model<Foo>
{

}

并创建一个列表:

var fooList = new List<Foo>();

如果你能将它转换为List<Model<Foo>>
var modelList = (List<Model<Foo>>) fooList ; // not possible

如果你能够添加新的条形图到列表中,那么就可以了:
modelList.Add(new Bar());

但这仍然是一个 Foo 列表,它可能只有 Foo 对象。
作为解决方案,您可以尝试将 Role 强制转换为 Model:
static List<Model<T>> Get<T>(string value)  where T:Model<T>
{
    switch (value)
    {
        case "ROLE":
            return GetRoles().Cast<Model<T>>().ToList();
            break;
    }
    return new List<Model<T>>();
}

好的,我理解了。但是有没有解决这个任务的方法?我需要在value之间切换并返回一些Model<T>列表。 - A. Akzhigitov

1
问题在于List<T>不是协变的。这意味着如果你允许这样做,调用者会认为它有一个List<Model<T>>,但实际上它会有一个List<Role> - 如果你尝试向列表中添加另一个从Model<T>派生的类的实例,它将失败。C#不允许你这样做。
相反,你可以使用以下方式显式地将结果转换为List<Model<T>>:
return new List<Model<T>>(GetRoles());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接