Dictionary<int, ArrayList> Deduction_Employees =
new Dictionary<int, ArrayList>();
后来我向该数组列表添加了一个像这样的匿名类型
var day_and_type = new {
TheDay = myDay,
EntranceOrExit = isEntranceDelay
};
Deduction_Employees[Employee_ID].Add(day_and_type);
现在我怎样才能取消该var并访问这些属性?
答案 0 :(得分:13)
首先,您不是拆箱类型。匿名类型是引用类型,而不是结构。
即使你可以在声明它们的方法之外技术上创建相同类型的实例(根据C#3.0语言规范的7.5.10.6节,其中声明:
在同一个程序中,两个匿名 指定a的对象初始值设定项 它的属性序列 中的名称和编译时类型 相同的顺序将产生实例 相同的匿名类型。
)您无法获取该类型的名称,以便从Object
执行强制转换回您创建的类型。你不得不诉诸cast-by-example solution,这本身就是有缺陷的。
逐个示例是有缺陷的,因为从设计的角度来看,每个想要访问它所声明的函数之外的类型的地方(并且仍在同一个模块中),你必须有效地再次声明类型
这是一种重复的努力,导致设计和实施的草率。
如果您使用的是.NET 4.0,那么可以将对象实例放在动态变量中。但是,主要缺点是缺乏成员访问的编译时验证。您可能很容易拼错该成员的名称,然后您遇到运行时错误而不是编译时错误。
最终,如果您发现需要在声明的方法之外使用匿名类型,那么唯一的好方法是创建具体类型并将匿名类型替换为具体类型
答案 1 :(得分:8)
有几种方法。
由于评论似乎表明我建议你这样做,让我说清楚:你应该为你的对象创建一个命名类型,因为你打算传递它。
首先,您可以使用Reflection,这里已经指出了另一个答案。
另一种方法,它使.NET成为正确的类型被称为“按示例执行”,它是这样的:你需要通过泛型方法调用传递你的对象,它会将对象返回为正确的类型,通过推断正确的类型返回。
例如,试试这个:
private static T CastByExample<T>(T example, object value)
{
return (T)value;
}
并使用它:
var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);
两个??斑点,您只需要传递适合这些属性的数据类型的东西,不会使用这些值。
这利用了这样一个事实:在同一个程序集中,包含完全相同属性,相同类型,相同顺序的多个匿名类型将映射到同一个单一类型。
但是,此时您应该创建一个命名类型。
答案 2 :(得分:3)
匿名类型具有方法范围。要在方法边界外传递匿名类型或包含匿名类型的集合,必须先将类型转换为对象。然而,这打败了匿名类型的强类型。如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类而不是匿名类型。
答案 3 :(得分:1)
不,你不能。您只能使用反射访问属性。编译器无法知道类型是什么,并且由于它是匿名类型,因此您也无法将其强制转换。
答案 4 :(得分:1)
如果您使用的是.NET 1.x - 3.x,则必须使用反射。
如果使用.NET 4.0,则可以使用动态类型并调用预期的属性。
在这两种情况下你都不需要拆箱;这是价值类型。匿名类型始终是引用类型。