考虑代码:
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&lt; string&gt; 是 List&lt; object&gt;,因为字符串是一个对象,C#4应该支持泛型类型的协方差。
答案 0 :(得分:3)
您收到错误是因为List<string>
不是List<object>
。
您可以在list.Add(new TextBox())
上致电List<object>
,但很明显,同一通话对List<string>
无效。
如果泛型类型是不可变的,那么C#泛型只允许Covariance(这是我从List到IEnumerable的转换)。
如果您需要将列表传递给方法,可以尝试传递
listOfStrings.Cast<object>();
缺点是,如果使用该解决方案,对方法调用内的列表所做的任何修改都不会反映在原始列表中(因为对Cast
的调用会创建一个新列表)。
如果您控制方法INeedToPassThisMethodAListOfObjects
并且该方法只需要迭代集合而不是修改它,您可以将参数类型更改为IEnumerable<object>
,在这种情况下您只需要能够毫无问题地通过你的List<string>
。
答案 1 :(得分:3)
接口可以是变体;班级不能。 See here for the explanation.
如果您未通过strings
集合并将声明更改为
static void INeedToPassThisMethodAListOfObjects(IEnumerable<object> objects) { }
但是,这取决于您是否需要此功能中的List
。
答案 2 :(得分:2)
您必须将字符串转换为对象。这是一个很好的LINQ方法。
var strings = new List<string>();
INeedToPassThisMethodAListOfObjects(strings.Cast<object>());
修改强>
根据您自己的链接,
在C#中,以下情况支持方差:
数组中的协方差(自C#1.0起)
代表中的协方差和逆变,也称为“方法组差异”(自C#2.0起)
接口和代理中的泛型类型参数的差异(自C#4.0起)
所以IEnumerable会接受List