我有一个KeyValuePairs列表.我通常会用ToDictionary
.
但是我只是注意到错误消息(如下所示)有关于显式强制转换的内容,这意味着我实际上可以将列表转换为Dictionary<...>
.我怎样才能做到这一点?
Cannot implicitly convert type 'System.Linq.IOrderedEnumerable<System.Collections.Generic.KeyValuePair<int,string>>' to 'System.Collections.Generic.Dictionary<int, string>'. An explicit conversion exists (are you missing a cast?)
示例代码:
Dictionary<int, string> d = new Dictionary<int, string>() {
{3, "C"},
{2, "B"},
{1, "A"},
};
var s = d.OrderBy(i => i.Value);
d = s;
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 69
意味着我实际上可以将列表转换为字典
好吧,这意味着演员阵容在编译时是有效的.这并不意味着它将在执行时工作.
这是可能的,这个代码可以工作:
IOrderedEnumerable<KeyValuePair<string, string>> pairs = GetPairs();
Dictionary<string, string> dictionary = (Dictionary<string, string>) pairs;
Run Code Online (Sandbox Code Playgroud)
...但仅当返回的值GetPairs()
是从中派生的类时才Dictionary<,>
实现IOrderedEnumerable<KeyValuePair<string, string>>
.这是非常不可能的,这是实际上在正常代码的情况.编译器不能阻止你尝试,但它不会很好地结束.(特别是,如果你使用问题中的代码并使用标准的LINQ to Objects执行它,它肯定会在执行时失败.)
你应该坚持ToDictionary
......虽然你也应该意识到你将失去订单,所以没有必要订购它.
要在您的问题中显示以下代码:
Dictionary<int, string> d = new Dictionary<int, string>() {
{3, "C"},
{2, "B"},
{1, "A"},
};
var s = d.OrderBy(i => i.Value);
d = (Dictionary<int, string>) s;
Run Code Online (Sandbox Code Playgroud)
编译,但在执行时失败,如预测:
未处理的异常:System.InvalidCastException:无法将类型的对象强制转换
'System.Linq.OrderedEnumerable`2[System.Collections.Generic.KeyValuePair`2[System.Int32,System.String],System.String]'
为类型'System.Collections.Generic.Dictionary`2[System.Int32,System.String]'
.
在Test.Main()
作为一个背景,你总是可以从任何接口类型转换为非密封类("目标"),即使该类型没有实现接口,因为从"目标"派生的另一个类可以实现界面.
从C#5规范的6.2.4节:
显式引用转换是:
- ...
- 从任何类类型
S
到任何接口类型T
,提供S
的都不是密封的,并且提供S
不实现T
.- ...
(其中,壳体S
不实施T
由隐式引用转换覆盖.)
如果您尝试隐式转换值并且没有可用的隐式转换,但是有可用的显式转换,编译器将在您的问题中给出警告.这意味着您可以使用强制转换修复编译器错误,但您需要了解它在执行时失败的可能性.
这是一个例子:
using System;
class Test
{
static void Main()
{
IFormattable x = GetObject();
}
static object GetObject()
{
return DateTime.Now.Second >= 30 ? new object() : 100;
}
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
Test.cs(7,26): error CS0266: Cannot implicitly convert type 'object' to
'System.IFormattable'. An explicit conversion exists (are you missing a cast?)
Run Code Online (Sandbox Code Playgroud)
所以我们可以添加一个演员:
IFormattable x = (IFormattable) GetObject();
Run Code Online (Sandbox Code Playgroud)
此时,代码将工作大约一半的时间 - 另一半,它将抛出异常.
归档时间: |
|
查看次数: |
10445 次 |
最近记录: |