2

考虑代码:

using System.Collections.Generic;
namespace TestingTypes
{
    class Program
    {
        static void Main(string[] args)
        {
            var strings = new List<string>();               
            INeedToPassThisMethodAListOfObjects(strings as List<object>);
        }

        static void INeedToPassThisMethodAListOfObjects(List<object> objects) { }
    }
}

1>------ Build started: Project: TestingTypes, Configuration: Debug Any CPU ------
1>c:\users\[censored]\TestingTypes\Program.cs(9,41,9,64): error CS0039: Cannot convert 
type 'System.Collections.Generic.List<string>' to 
'System.Collections.Generic.List<object>' via a reference conversion, boxing 
conversion, unboxing conversion, wrapping conversion, or null type conversion

您可能会说 List<string>List<object>,因为字符串是对象,而 C# 4 应该支持泛型类型中的协变。

  • 为什么编译器说它不能转换类型?
  • 如何将“字符串”传递给方法?
4

3 回答 3

3

您收到错误是因为 aList<string>不是List<object>.

你可以打电话list.Add(new TextBox())List<object>但很明显,同样的电话在List<string>.

如果泛型类型是不可变的(这是我从 List 转换为 IEnumerable 的工作),C# 泛型仅允许协变。

如果您需要将列表传递给方法,您可以尝试传递

listOfStrings.Cast<object>();

不利的一面是,如果您使用该解决方案,则在方法调用中对列表所做的任何修改都不会反映在原始列表中(因为调用会Cast创建一个新列表)。

如果您可以控制该方法INeedToPassThisMethodAListOfObjects并且该方法只需要迭代集合而不是修改它,您可以将参数类型更改为IEnumerable<object>在这种情况下您可以简单地传递您的集合而List<string>不会出现任何问题。

于 2012-10-24T17:04:54.660 回答
3

接口可以变体;类不能。有关说明,请参见此处。

如果您通过未转换的strings集合并将声明更改为,您的代码将起作用

static void INeedToPassThisMethodAListOfObjects(IEnumerable<object> objects) { }

但是,这取决于您是否需要List在此函数中使用 a。

于 2012-10-24T17:08:07.423 回答
2

您必须将字符串转换为对象。有一个很好的 LINQ 方法可以做到这一点。

var strings = new List<string>();               
INeedToPassThisMethodAListOfObjects(strings.Cast<object>());

编辑

根据你自己的链接,

在 C# 中,在以下情况下支持方差:

  • 数组中的协方差(自 C# 1.0 起)

  • 委托中的协变和逆变,也称为“方法组方差”(自 C# 2.0 起)

  • 接口和委托中泛型类型参数的变化(自 C# 4.0 起)

所以 IEnumerable 会接受 List

于 2012-10-24T17:06:29.003 回答