【问题标题】:add duck-typed struct to dictionary c#将鸭子类型的结构添加到字典 c#
【发布时间】:2018-11-18 07:31:00
【问题描述】:

我想在字典中添加一个鸭子类型的结构,但我收到以下错误:

参数 2:无法从 '[] options>' 转换为 '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#,所以很抱歉初学者的错误。但我似乎真的找不到如何让它发挥作用。
如果有不清楚的地方请告诉我,以便我澄清..

【问题讨论】:

  • 创建一个可以容纳句子的类会更容易,因为鸭式打字很容易出错
  • 您使用的是UnityEngine.Object 而不是System.Object,可能是因为您只导入了Unity 的东西。要修复它,请在字典声明中使用 System.Object 或导入正确的命名空间
  • @Freggar 感谢这项工作!如果您将其写为答案,我会接受。

标签: c# dictionary unity3d duck-typing


【解决方案1】:

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

参数 2:无法从 '[] options>' 转换为 'UnityEngine.Object'

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

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

using UnityEngine;

在您的命名空间中。 C# 的问题在于它的Object 类也驻留在名为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 的别名。可是等等!不管我们的 using 语句如何,这不会使 object 总是 使用 System.Object 吗?答案是肯定的,是的……

让我通过以下示例说明 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
    }
}

这是否意味着我们在使用系统类时应该始终使用内置别名?并非如此,但我们应该宁愿使用 Microsoft 使用的命名约定。这意味着无论何时您像使用数据类型一样使用类时,都应该使用内置的类,而无论何时使用类的静态成员,都应该使用它的全名。例如:

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

【讨论】:

    【解决方案2】:

    强类型是 C# 的优点之一,它比鸭子类型更冗长,但可以省去很多麻烦,如果可能的话,尽量避免使用 var,它的几个字符更短,但如果你使用强类型,那就更难了不小心要求编译器做一些与你真正想要的不同的事情:

    两种似乎立即脱颖而出的替代方法是

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

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

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

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

    也许你想把上面的组合成

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

    【讨论】:

      猜你喜欢
      • 2018-10-11
      • 2021-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多