Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型的协方差/转换问题_C#_Generics - Fatal编程技术网

C# 泛型的协方差/转换问题

C# 泛型的协方差/转换问题,c#,generics,C#,Generics,以代码为例: using System.Collections.Generic; namespace TestingTypes { class Program { static void Main(string[] args) { var strings = new List<string>(); INeedToPassThisMethodAListOfObj

以代码为例:

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
使用System.Collections.Generic;
命名空间测试类型
{
班级计划
{
静态void Main(字符串[]参数)
{
var strings=新列表();
INEEDTopassThisMethodAlistOfObject(字符串作为列表);
}
静态无效IneedToPassThisMethodAlistOfObject(列表对象){}
}
}
1> ----构建已启动:项目:测试类型,配置:调试任何CPU------
1> c:\users\[censtered]\TestingTypes\Program.cs(9,41,9,64):错误CS0039:无法转换
键入“System.Collections.Generic.List”以
“System.Collections.Generic.List”通过引用转换、装箱
转换、取消装箱转换、换行转换或空类型转换
你可以说列表就是一个列表,因为字符串是一个对象,而C#4应该支持泛型类型中的协方差

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

您收到错误是因为
列表
不是
列表

您可以在
list
上调用
list.Add(new TextBox())
,但显然,相同的调用在
list
上不起作用

C#泛型只允许在泛型类型不可变的情况下使用协方差(这是从列表到IEnumerable工作的转换)

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

listOfStrings.Cast<object>();
listofstring.Cast();
另一方面,如果使用该解决方案,对方法调用中的列表所做的任何修改都不会反映在原始列表中(因为对
Cast
的调用会创建一个新列表)


如果您控制了INeedToPassThisMethodAListOfObjects方法
,并且该方法只需在集合上迭代,而不需要修改它,您可以将参数类型更改为
IEnumerable
,在这种情况下,您只需传递
列表
,而不会出现任何问题。

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

var strings = new List<string>();               
INeedToPassThisMethodAListOfObjects(strings.Cast<object>());
var strings=newlist();
IneedToPassThisMethodAlistOfObject(strings.Cast());
编辑

根据你自己的链接

在C#中,在以下场景中支持方差:

  • 阵列中的协方差(自C#1.0起)

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

  • 接口和委托中泛型类型参数的差异(自C#4.0以来)


因此IEnumerable将接受列表

接口可以是变量;类不能

如果将
字符串
集合传递为uncasted并将声明更改为

static void INeedToPassThisMethodAListOfObjects(IEnumerable<object> objects) { }
static void inedtopassthis方法论对象(IEnumerable对象){

但是,这取决于您是否需要此函数中的
列表。

是的,它有点像:@BarryFandango-实际上不是。注意这篇文章。列表是一个IEnumerable。这是因为IEnumerable对象是不可变的(正如我在回答中所说的),我真的不知道你为什么被否决。解释得很好:)否决票是基于贾斯汀最初的答案,这只是第一行。虽然帮不上什么忙,但他还是排在了队伍的最前面。随着我的观看,它变得越来越充实。或者像我在另一个答案中评论的那样使用
IReadOnlyList
(从.NET 4.5开始)。
strings.Cast()
在语义上更加正确,因为所有字符串都是
object
类型。感谢大家,Tim奖颁给你,因为你是第一个注意到类类型差异与接口的人。我不是第一个注意到这一点吗?我不在乎分数,所以就这样说吧:)啊,普鲁克,你完全正确,你让蒂姆·罗杰斯在我看来领先了90秒。感谢您的帮助。如果@BarryFandango需要列表功能,在.NET 4.5及更高版本中,他可以使用
void方法(IReadOnlyList对象)
。接口
IReadOnlyList
T
中是协变的,
List
T[]
以及其他接口实现
IReadOnlyList