使用匿名对象初始化字典

本文关键字:初始化 字典 对象 | 更新日期: 2023-09-27 18:26:56

>我正在尝试执行以下操作。

private static Dictionary<int, object> MAPS = new Dictionary<int, object>
{
  {1, new {1, 2, 3}}
};

它没有像我基于 MSDN 预期的那样工作,所以我很确定问题是我使用的是匿名对象。假设我不想为我的东西创建一个新类型,并且仍然想将所有映射保留在同一字典中,我该怎么办?

我已经看到了这个答案,但现在它有点过时了,所以我希望框架中有一些新的东西。

使用匿名对象初始化字典

如果你想要一个 int s 的数组作为值,试试这个。

private static Dictionary<int, object> MAPS = new Dictionary<int, object>
{
  {1, new[] {1, 2, 3}}
};

或者如果你想要一个匿名类

private static Dictionary<int, object> MAPS = new Dictionary<int, object>
{
  {1, new { a = 1, b = 2, c = 3}}
};

或者更好的是不要使用object. 对int集合使用 int[]List<int>,如果需要特定值,请声明类或结构。 如果您只需要每个值 3 int s,甚至可以使用 Tuple<int,int,int>。 但是,一般来说,您应该尽量避免在object之间投射的需要。

进一步了解 @TimSchmelter 和 @juharr 的答案,如果您希望能够通过属性的名称引用属性,但又不想创建一个可以使用dynamic的类(尽管显然您不会获得任何智能感知,因此它的使用受到限制(:

Dictionary<int, object> MAPS = new Dictionary<int, object>
{
    {1, new { a = 1, b = 2, c = 3} as dynamic}
};
Console.WriteLine(((dynamic)MAPS[1]).b); //prints 2

或者,如果你把Dictionary Dictionary<int, dynamic>你可以放弃演员阵容,这让生活更轻松一些:

Dictionary<int, dynamic> MAPS = new Dictionary<int, object>
{
    {1, new { a = 1, b = 2, c = 3}}
};
Console.WriteLine(MAPS[1].b); //prints 2

使用 objectdynamic 的唯一好处是,您可以在其中存储具有不同类型的集合。如果您只存储int,那么最好使用 List<int>int[] .

匿名类型只是具有属性的类型,您的匿名类型没有属性:

private static Dictionary<int, object> MAPS = new Dictionary<int, object>
{
    {1, new { Prop1 = 1, Prop2 = 2, Prop3 = 3}}
};

但是你想如何从对象投射到那个匿名类型呢?

编辑不过,那里有个好问题。我是否必须强制转换 MAPS[1][0],或者有没有办法在那里隐式

强制类型?

如果没有像以下扩展方法这样的黑客,则无法将对象转换为匿名类型:

public static T CastByPrototype<T>(this object obj, T prototype)
{
    return (T)obj;
}

它使用原型匿名类型,如下所示:

var prototype = new { Prop1 = 0, Prop2 = 0, Prop3 = 0 };

现在这有效:

var value = MAPS[1].CastByPrototype(prototype);  // you can use value.Prop1

如果原型具有不相同的属性(以相同的顺序(,则失败并显示InvalidCastException

语法

new {1, 2, 3}不是集合初始值设定项,也不是匿名对象初始值设定项。要创建什么类型的对象?

使用类似于 new { elements = new[] { 1, 2, 3 } } 的内容为匿名对象提供包含整数的 elements 属性。

或者,您可以将各个属性命名为:new { foo = 1, bar = 2, baz = 3 }