C# 无法在方法调用中将字典转换为IDictionary
我一辈子都搞不清楚这件事。假设我有以下两个dictionary对象:C# 无法在方法调用中将字典转换为IDictionary,c#,.net,type-conversion,covariance,implicit-conversion,C#,.net,Type Conversion,Covariance,Implicit Conversion,我一辈子都搞不清楚这件事。假设我有以下两个dictionary对象: // Assume "query" is a LINQ queryable. Dictionary<string, int> d1 = query.ToDictionary(k => k.Key, v => v.Value); Dictionary<string, int> d1 = query.ToDictionary(k => k.Key, v => v.Value);
// Assume "query" is a LINQ queryable.
Dictionary<string, int> d1 = query.ToDictionary(k => k.Key, v => v.Value);
Dictionary<string, int> d1 = query.ToDictionary(k => k.Key, v => v.Value);
//假设“query”是一个LINQ查询表。
字典d1=query.ToDictionary(k=>k.Key,v=>v.Value);
字典d1=query.ToDictionary(k=>k.Key,v=>v.Value);
以下语句生成编译时错误,无法在字典和IDictionary之间进行隐式转换:
// Compile time error!
Tuple<IDictionary<string, int>, IDictionary<string, int>> = Tuple.Create(d1, d2);
//编译时错误!
Tuple=Tuple.Create(d1,d2);
我必须明确地进行转换:
Tuple<IDictionary<string, int>, IDictionary<string, int>> = Tuple.Create(d1 as IDictionary<string, int>, d2 as IDictionary<string, int>);
Tuple=Tuple.Create(d1作为IDictionary,d2作为IDictionary);
我不理解为什么编译器不能计算协方差运算-字典实现IDictionary-尤其是因为我们都知道这样的东西当然可以工作:
IDictionary<string, int> d3 = d1;
IDictionary d3=d1;
我确信这种行为有很好的理由,我很好奇它是什么
更新1:
我只是想澄清一下,我对行为感到好奇,而不是对如何解决问题感到好奇。我知道不同的解决方案:)
更新2:
谢谢大家的回答。我不知道
Tuple
是不变的,现在我知道了。尝试将变量类型从Dictionary
更改为IDictionary。
IDictionary d1=query.ToDictionary(k=>k.Key,v=>v.Value);
IDictionary d1=query.ToDictionary(k=>k.Key,v=>v.Value);
Tuple.Create的类型参数是从类型中推断出来的,因此右侧是一个包含两个字典的Tuple,这与IDictionarys的Tuple是不同的类型-如果您显式地将类型参数添加到Tuple.Create为IDictionary类型,那么一切都应该按预期工作,因为该方法没有问题参数应为更具体的类型
Tuple.Create<IDictionary<string, int>,IDictionary<string, int>>(d1,d2)
Tuple.Create(d1,d2)
基本上,问题在于Tuple
族的类型参数不协变。不可能,因为这是一门课。但是,可以创建协变的接口或委托版本,因为在输入位置没有接受类型参数的成员
这是最简单的:
。。。正在将这两个类型参数推断为字典
,因此您正在尝试从元组
转换为
元组
,它不起作用
带有as
的版本更改了参数类型,以便类型推断提供所需的类型参数-但根据Sebastian的回答,直接编写类型参数并完全避免推断会更简单:
Tuple.Create<IDictionary<string, int>, IDictionary<string, int>>(d1, d2)
x
的类型现在将是Tuple
,这正是您想要的
编辑:如注释中所述,您最好在此时使用构造函数:
var x = new Tuple<IDictionary<string, int>, IDictionary<string, int>>(d1, d2);
var x=新元组(d1,d2);
由于C#中的类(因此元组
类)不支持协方差,因此元组
和元组
之间没有转换
编译器已为您对Tuple.Create
的调用推断出返回类型的最具体类型,并且在推断过程中不使用左侧的类型。您正在尝试分配
Tuple<Dictionary<string, int>, Dictionary<string, int>>
元组
…到
Tuple<IDictionary<string, int>, IDictionary<string, int>>
元组
…但是元组是一个类,因此可以工作。但我对这种行为很好奇,因为如果我使用隐式类型变量声明,例如,vard1=query.ToDictionary(k=>k.Key,v=>v.Value)代码>它不会工作。我想问题是,为什么我必须手动进行转换?通过使用var,编译器会将类型设置为Dictionary,因为Enumerable.ToDictionary返回Dictionary而不是IDictionary。你是对的。我把我的意思打错了。我想问为什么传递query.ToDictionary(k=>k.Key,v=>v.Value)
不起作用。谢谢你的回答。谢谢你的详细回答。所有的答案都很好,但由于给出的细节,我将这一个标记为答案。@agarhy当然,当(像这里)需要显式指定静态元组的类型参数T1
和T2
。Create
方法,您还可以使用泛型类型Tuple
的普通实例构造函数和一个新的对象表达式:newtuple(d1,d2)
var x = Tuple.Create<IDictionary<string, int>, IDictionary<string, int>>(d1, d2);
var x = new Tuple<IDictionary<string, int>, IDictionary<string, int>>(d1, d2);
Tuple<Dictionary<string, int>, Dictionary<string, int>>
Tuple<IDictionary<string, int>, IDictionary<string, int>>