如何将字典转换为我的类实现相同类型的字典?

ibi*_*iza 4 c# generics type-conversion

如果我有

public class Stats : Dictionary<string, double>
{
}

public class Info : Dictionary<string, Stats>
{
}
Run Code Online (Sandbox Code Playgroud)

var data = new Dictionary<string, Dictionary<string, double>> {
    { "1", new Dictionary<string, double> {  { "a", 11 } } },
    { "2", new Dictionary<string, double> {  { "aa", 111 } } },
};
Run Code Online (Sandbox Code Playgroud)

为什么我不能这样做:

var test = (Info)data;
Run Code Online (Sandbox Code Playgroud)

以及我需要使用什么运算符或代码才能实例化我的

[class inheriting from a Dictionary<string, Dictionary<string, double>>]

从一个

Dictionary<string, Dictionary<string, double>>?

Pet*_*iho 5

你的方法确实有两个不同的错误:

  1. Dictionary<string, Stats>不一样Dictionary<string, Dictionary<string, double>>。认为Info是继承是错误的Dictionary<string, Dictionary<string, double>>。它继承了Dictionary<string, Stats>,这是完全不同的。
  2. 即使您获得了正确的基类型,也不能只是将基类型的任何随机实例转换为派生类型。有关讨论此问题的众多现有堆栈溢出问答主题之一,请参阅将基类型转换/转换为派生类型

如果没有一个好的最小、完整和可验证的代码示例,就不可能确定你的代码是如何工作的,或者需要什么才能让它做你想做的事。但是在您的特定示例中,您可能能够声明显式转换,当您使用 cast 运算符时将调用该转换。

例如:

public class Info : Dictionary<string, Stats>
{
    public static explicit operator Info(Dictionary<string, Dictionary<string, double>> source)
    {
        Info result = new Info();

        foreach (var kvp in source)
        {
            result.Add(kvp.Key, Stats.FromDictionary(kvp.Value));
        }

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

在哪里:

public class Stats : Dictionary<string, double>
{
    public static Stats FromDictionary(Dictionary<string, double> source)
    {
        Stats result = new Stats();

        foreach (var kvp in source)
        {
            result.Add(kvp.Key, kvp.Value);
        }

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,我们希望能够在以下方面做类似的事情Info

public class Stats : Dictionary<string, double>
{
    public static explicit operator Stats(Dictionary<string, double> source)
    {
        Stats result = new Stats();

        foreach (var kvp in source)
        {
            result.Add(kvp.Key, kvp.Value);
        }

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

但这是一个编译器错误:

Stats.explicit operator Stats(System.Collections.Generic.Dictionary)':不允许用户定义的与基类之间的转换

这在此处得到了更彻底的解决:来自基类的用户定义的转换运算符。简短的版本是,如果编译器允许这样做,那么如果您尝试从基本引用转换为派生引用,那么意图是什么就会不明确。在这种情况下,语言迫使您要明确。

那么您要使用的语句将起作用:

var test = (Info)data;
Run Code Online (Sandbox Code Playgroud)

说了这么多,你在评论中写道:

该类只是为了清理代码并使用我的类名而不是Dictionary<string, Dictionary<string, double>>无处不在

如果是这种情况,那么您可能只想使用类型名称别名而不是继承。例如:

using Stats = System.Collections.Generic.Dictionary<string, double>;
using Info = System.Collections.Generic
    .Dictionary<string, System.Collections.Generic.Dictionary<string, double>>;
Run Code Online (Sandbox Code Playgroud)

然后,您可以分别使用StatsInfoDictionary<string, double>和互换名称Dictionary<string, Dictionary<string, double>>