2014-10-17 30 views
1

我正在尝试执行以下操作。使用匿名对象初始化字典

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

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

我见过this answer但现在有点过时了,所以我希望在框架中有一些新的东西。

+1

而不是说_“不能像我期望的那样工作_如果你显示实际的编译器错误,这将是有帮助的,它是_”无效的匿名类型成员声明器。匿名类型成员必须声明为成员分配,简单名称或成员访问“_。 – CodeCaster 2014-10-17 11:29:26

+0

@CodeCaster采取点。我认为这是一个基本的东西,我刚刚得到了一个大脑噗噗。但你是正确的,没有争论。 :) – 2014-10-17 11:31:43

回答

3

如果你想要一个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[]List<int>作为int的集合或声明类或结构。如果您只需要每个值需要3 int s,甚至可以使用Tuple<int,int,int>。但是,一般而言,您应该尽量避免需要投入并从object

+0

哦,我尝试在** **新操作符**和**角度的对象类型**上设置括号。我试过冒号而不是平等标志。愚蠢的JSON损坏了我...... :) +1 – 2014-10-17 11:24:55

+0

是否可以输入* a *。 * b *和* c *没有为他们申报班级? – 2014-10-17 11:30:12

+0

他们将隐式采取您设置它们的类型,所以如果需要,您可以施放该值。但是,您在这里使用匿名类时遇到的主要问题是,当您从字典中提取值时,无法投射。你可能想用'dynamic'来代替'object'。 – juharr 2014-10-17 11:34:07

1

语法new {1, 2, 3}not a collection initializer nor an anonymous object initializer。你想创建什么类型的对象?

使用类似new { elements = new[] { 1, 2, 3 } }的东西给匿名对象一个elements包含整数的属性。

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

+0

我想有一个字典,给定的整数给了我两个不同的整数。 – 2014-10-17 11:23:35

1

匿名类型仅仅是一个性质类型,您的anonymus类型没有属性:

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

但你要如何从对象转换到anoymous类型?

编辑虽然这里有一个很好的问题。我必须投射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如果原型ype具有不同的属性(以相同的顺序)。

+1

呵呵,@juharr打败你。慢手指日? ;) – 2014-10-17 11:27:13

+0

虽然这里有个好问题。我必须施放* MAPS [1] [0] *还是有办法在那里隐式强制类型? – 2014-10-17 11:29:28

+0

@KonradViltersten如果你想通过'MAPS [1] [0]'获得一个值,那么为什么不把它变成'Dictionary '或者'Dictionary >'而不是? – juharr 2014-10-17 11:37:53

1

除了@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 

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