【问题标题】:Cast Dictionary<int, Object1> to Dictionary<int, Object2>将 Dictionary<int, Object1> 转换为 Dictionary<int, Object2>
【发布时间】:2020-07-22 14:18:45
【问题描述】:

我有这两个对象、一个字典和一个方法

public abstract  class Thing {}
public class Star : Thing {}

Dictionary<int, Star> dictStar;

public void listBoxAdd (Listbox listBox, Dictionary<int, Thing> thingDict){}

我想用 dictStar 调用方法。我尝试了一堆东西来转换我的字典,但我尝试过的都没有奏效。我认为这应该可行,但编译器不同意。

listBoxAdd (starList, ( Dictionary<int, Thing>) dictStar);

我收到一个错误 CS0030,即 c# 无法将星形字典转换为事物字典。

还有其他几个基于事物的类,我的设计需要将它们的字典传递给将在事物中的字段上工作的方法。有好几次我的方法只需要访问 Thing 中定义的东西。

我没有问题将星投射到事物上,但我的字典有问题。我尝试让该方法采用 int、object 的字典,我可以调用,但在该方法中我无法将 Dictionary of Objects 转换为 Tings。

如果我在这两种方法中都使用 Star Dictionaries 并调用它就可以正常工作。

我什至使用了 Thing 的基类和 Star 派生自它。

我来自 64K 大型机的旧时代,并且一直在考虑内存使用情况和机器周期,因此,除了不优雅之外,通过字典和调用每个元素,虽然它会起作用,但这似乎是个坏主意.

我知道很多规则都用于允许 c# 清理内存中未使用的内容,但在调用期间元素没有消失的危险。

【问题讨论】:

标签: c# dictionary object casting


【解决方案1】:

我将解释为什么它被 C# 禁止。让我们定义第二个子类public class BlackHole : Thing {}

现在,如果您可以尝试将星星字典转换为事物字典 var dicThings = (Dictionary&lt;int, Thing&gt;) dictStar

您可以稍后再写dicThings.Add(5, new BlackHole());,但有一个问题:runtime 类型的 dicThings 仍然是一个包含黑洞的恒星字典。


解决方案:

您可以将您的方法转换为具有类型约束的泛型,例如listBoxAdd&lt;T&gt; .... where T : Thing


这是一个完整的示例代码:

using System;
using System.Collections.Generic;

public class Program
{
    public abstract  class Thing {}
    public class Star : Thing {}
    public class BlackHole : Thing {}

    public static void DoThing (Dictionary<int, Thing> thingDict) { Console.WriteLine("DoThing"); }

    public static void DoThingMagic<T> (Dictionary<int, T> thingDict) where T : Thing { Console.WriteLine("DoThingMagic"); }

    public static void Main()
    {
        Dictionary<int, Star> dictStars = new Dictionary<int, Star>();

        // line below has a compilation error to protect you from mixing stars with black holes ;)
        Dictionary<int, Thing> dictThings = (Dictionary<int, Thing>) dictStars;
        // it explains the method call has a compilation error too:
        DoThing(dictStars);

        // now this method call will compile and execute:
        DoThingMagic(dictStars);
    }
}

【讨论】:

  • @Peter 另外我们说 Dictionary 不是协变的,因为 dicStars 确实转换为 dicThings,尽管 Star 是一个事物。注意:很高兴在 64K 大型机上认识您;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 2011-03-05
  • 2010-10-17
  • 2020-02-03
相关资源
最近更新 更多