转换包含通用字典的通用字典

发布于 2024-10-31 19:13:29 字数 827 浏览 3 评论 0 原文

我有:

var someConcreteInstance = new Dictionary<string, Dictionary<string, bool>>();

并且我希望将其转换为接口版本,即:

someInterfaceInstance = (IDictionary<string, IDictionary<string, bool>>)someConcreteInstance;

“someInterfaceInstance”是公共属性:

IDictionary<string, IDictionary<string, bool>> someInterfaceInstance { get; set; }

这可以正确编译,但会引发运行时转换错误。

Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.Dictionary`2[System.String,System.Boolean]]' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Collections.Generic.IDictionary`2[System.String,System.Boolean]]'.

我缺少什么? (嵌套泛型类型/属性有问题吗?)

I have:

var someConcreteInstance = new Dictionary<string, Dictionary<string, bool>>();

and I wish to cast it to an interface version, i.e.:

someInterfaceInstance = (IDictionary<string, IDictionary<string, bool>>)someConcreteInstance;

'someInterfaceInstance' is a public property:

IDictionary<string, IDictionary<string, bool>> someInterfaceInstance { get; set; }

This compiles correctly, but throws a runtime casting error.

Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.Dictionary`2[System.String,System.Boolean]]' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Collections.Generic.IDictionary`2[System.String,System.Boolean]]'.

What am I missing? (Problems with the nested generic type/Property?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我偏爱纯白色 2024-11-07 19:13:29

其他答案是正确的,但为了清楚地说明为什么这是非法的,请考虑以下事项:

interface IAnimal {}
class Tiger : IAnimal {}
class Giraffe : IAnimal {}
...
Dictionary<string, Giraffe> d1 = whatever;
IDictionary<string, IAnimal> d2 = d1; // suppose this were legal
d2["blake"] = new Tiger(); // What stops this?

没有凡人可以阻止您将老虎放入 IAnimals 字典中。但该词典实际上仅限于包含长颈鹿。

出于同样的原因,您也不能走其他路:

Dictionary<string, IAnimal> d3 = whatever;
d3["blake"] = new Tiger(); 
IDictionary<string, Giraffe> d4 = d3; // suppose this were legal
Giraffe g = d4["blake"]; // What stops this?

现在您将老虎放入长颈鹿类型的变量中。

仅当编译器能够证明不会出现此类情况时,通用接口协变才在 C# 4 中合法。

The other answers are right, but just to be crystal clear as to why this is illegal, consider the following:

interface IAnimal {}
class Tiger : IAnimal {}
class Giraffe : IAnimal {}
...
Dictionary<string, Giraffe> d1 = whatever;
IDictionary<string, IAnimal> d2 = d1; // suppose this were legal
d2["blake"] = new Tiger(); // What stops this?

No mortal hand can stop you putting a tiger into a dictionary of IAnimals. But that dictionary is actually constrained to contain only giraffes.

For the same reason you can't go the other way either:

Dictionary<string, IAnimal> d3 = whatever;
d3["blake"] = new Tiger(); 
IDictionary<string, Giraffe> d4 = d3; // suppose this were legal
Giraffe g = d4["blake"]; // What stops this?

Now you're putting a tiger in a variable of type giraffe.

Generic interface covariance is only legal in C# 4 if the compiler can prove that situations like this cannot arise.

蝶舞 2024-11-07 19:13:29

IDictionary 不支持协方差。

看这里
IDictionary在 .NET 4 中不是协变的

IDictionary does not support covariance.

Look here
IDictionary<TKey, TValue> in .NET 4 not covariant

許願樹丅啲祈禱 2024-11-07 19:13:29

您最多能做的是,

IDictionary<string, Dictionary<string, bool>> viaInterface = someConcreteInstance

您的内部字典不能在这里以不同方式引用(或通过强制转换)的原因是,虽然 Dictionary 是一个 IDictionary,并非所有 IDictionary 对象都是 Dictionary 对象。因此,获得纯接口转换似乎允许您将其他 > 对添加到原始集合,而显然可能存在类型违规原始对象。因此,这是不支持的。

The most you will be able to do is

IDictionary<string, Dictionary<string, bool>> viaInterface = someConcreteInstance

The reason your inner dictionary cannot be referenced differently here (or via a cast) is that while Dictionary<string, bool> is an IDictionary<string, bool>, not all IDictionary objects will be Dictionary objects. As such, obtaining a pure interface cast would then seemingly allow you to add other <string, IDictionary<string, bool>> pairs to the original collection, when clearly there could be type violations for the original object. Therefore, this is not supported.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文