【问题标题】:C# generic method valueC# 泛型方法值
【发布时间】:2017-01-28 10:03:28
【问题描述】:

我需要编写返回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&lt;Role&gt;,其中Role : Model&lt;Role&gt;
但 Visual Studio 告诉我它无法将 List&lt;Role&gt; 转换为 List&lt;Model&lt;T&gt;&gt;

【问题讨论】:

  • 为了将来参考,这是一个通用方法而不是模板函数。 C++ 模板和 C# 泛型相似但不相同 - 请参阅 msdn.microsoft.com/en-us/library/c6cyy67b.aspx
  • 类也是通用的?
  • 是的,只要您在 C# 中看到 &lt;...&gt;,它就是 generic 而不是 template

标签: c# .net linq templates generics


【解决方案1】:

这里的错误是List&lt;Role&gt;List&lt;Model&lt;T&gt;&gt; 不一样,即使RoleModel&lt;Role&gt;

例如,你有两个类:

public class Bar : Model<Foo>
{

}

public class Foo : Model<Foo>
{

}

并创建一个列表:

var fooList = new List<Foo>();

如果您可以将其转换为List&lt;Model&lt;Foo&gt;&gt;

var modelList = (List<Model<Foo>>) fooList ; // not possible

你应该能够将新的酒吧添加到列表中:

modelList.Add(new Bar());

但这仍然是Foo 的列表,它可能只有 Foo 对象。

作为一种解决方案,您可以尝试将角色转换为模型:

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&lt;T&gt; 列表。
【解决方案2】:

这里的问题是List&lt;T&gt; 不是协变的。这意味着如果你被允许这样做,调用者会认为它有一个List&lt;Model&lt;T&gt;&gt;,但实际上会有一个List&lt;Role&gt; - 如果你然后尝试将另一个派生自Model&lt;T&gt; 的类的实例添加到你的列出它会失败。 C# 不会让你这样做。

相反,您可以使用以下命令将结果显式转换为 List&lt;Model&lt;T&gt;&gt;

return new List<Model<T>>(GetRoles());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多