将鸭子类型的结构添加到字典 c#

add duck-typed struct to dictionary c#

我想将鸭子类型的结构添加到字典中,但出现以下错误:

Argument 2: cannot convert from '[] options>' to 'UnityEngine.Object'

这是我的代码:

public class Dynamic_Interface
{
    private static Dictionary<int, Object> Interface_steps = new Dictionary<int, Object>();

    Dynamic_Interface()
    {
        var sentences = new[] 
        {
            new
            {
                identifier = 1,
                text = "string explain",
                options = new[] 
                {
                    new
                    {
                        next = 2,
                        value = "this is the first option"
                    },
                    new
                    {
                        next = 2,
                        value = "this is the second option"
                    },
                    new
                    {
                        next = 2,
                        value = "this is the third option"
                    },
                    new
                    {
                        next = 2,
                        value = "this is the fourth option"
                    },
                }
            },
            new
            {
                identifier = 2,
                text = "string explain second var",
                options = new[] 
                {
                    new
                    {
                        next = 3,
                        value = "this is the second first option"
                    },
                    new
                    {
                        next = 3,
                        value = "this is the second second option"
                    },
                    new
                    {
                        next = 3,
                        value = "this is the second third option"
                    },
                    new
                    {
                        next = 3,
                        value = "this is the second fourth option"
                    }
                }
            },
        };

        foreach (var sentence_obj in sentences)
        {
            Interface_steps.Add(sentence_obj.identifier, sentence_obj);
        }
    }
}

所以最后我想要一个包含 sentences[] 中每个对象的字典,字典中的名称是 identifier key

我习惯了javascript,这真的是我第一次做c#,对于初学者的错误,我深表歉意。但我似乎真的找不到如何让它工作。
如果有什么不清楚的地方,请告诉我,以便我澄清..

强类型是 C# 的优点之一,它比 ducktyping 更冗长,但可以让你省去很多麻烦,如果可能的话,尽量避免使用 var,它会短几个字符,但如果你使用强类型,它会更有效更难意外地要求编译器做一些与您实际想要的不同的事情:

两个似乎立即脱颖而出的替代方法选项是

class myClass { int next; string value; };
Dictionary <int, myClass> dict;

或者,可能,虽然我认为这不是您想要做的事情

Dictionary<int, Dictionary<int,string>> dict; 

第二个选项不要求您声明 class 类型,但请记住字典需要唯一键。上面写着你想使用数组索引作为键,但你仍然使用字典,这是有原因的吗?我的解决方案可能有点偏离,但如果您能解释您想要进行哪种查找,我很乐意提出更多建议。

也许你想将以上组合成

Dictionary<int, Dictionary<int,myClass>> dict; 

那么,这里发生了什么?
当我们仔细查看错误信息时

Argument 2: cannot convert from '[] options>' to 'UnityEngine.Object'

它告诉我们,我们正在尝试将选项数组转换为类型 UnityEngine.Object。嗯。这很奇怪,我们没有用这种 Unity 废话定义我们的字典,那么为什么它使用它而不是 C# 的对象 class?!

好吧,您可能正在使用其他 Unity classes,可能有类似

的东西
using UnityEngine;

在您的命名空间中。 C# 的问题在于它的 Object class 也驻留在名为 System 的名称空间中,这使得它只能通过使用 System.Object 才能完全识别。所以如果你没有

using System;

当您键入 Object 时,它会很乐意尝试使用 UnityEngine.Object 而不是 System.Object。因此会出现这个奇怪的编译器错误。


所以只要用System.Object就可以了?
嗯,是的。但故事远不止于此!

C# 还为其最常见的类型定义了别名 - 即所谓的 built-in 类型:

bool        System.Boolean
byte        System.Byte
sbyte       System.SByte
char        System.Char
decimal     System.Decimal
double      System.Double
float       System.Single
int         System.Int32
uint        System.UInt32
long        System.Int64
ulong       System.UInt64
object      System.Object
short       System.Int16
ushort      System.UInt16
string      System.String

你会发现小写的object只是System.Object的别名。可是等等!这不会让 object 总是 使用 System.Object 而不管我们的 using 语句吗?答案是肯定的,是的...

让我通过以下示例说明 C# 中的命名空间实际上是多么棘手:

public class Object
{
    public string Name { get; set; }
}
public class TestConsole
{
    public static void Main(string[] args)
    {
        Object fakeObject = new Object(); // -> Custom Object class
        object realDeal = new object();   // -> System.Object

        string name = fakeObject.Name    // OK
        name = realDeal.Name             // NOT OK
    }
}

那么这是否意味着我们在使用 System classes 时应该始终使用内置别名?不完全是,但我们应该而不是 使用 Microsoft 使用的命名约定。这意味着每当你使用 class 作为数据类型时,你应该使用内置的,而每当你使用 class 的静态成员时,你应该使用它的全名。例如:

object humberto = "humberto";
string rudolf = "rudolf";
Object.Equals(humberto, rudolf);