匿名类型

Mus*_*gdy 6 c# unboxing anonymous-types

Dictionary(TKey, TValue)喜欢

Dictionary<int, ArrayList> Deduction_Employees = 
    new Dictionary<int, ArrayList>();
Run Code Online (Sandbox Code Playgroud)

后来我在这个数组列表中添加了这样的匿名类型

var day_and_type = new {
    TheDay = myDay,
    EntranceOrExit = isEntranceDelay
};

Deduction_Employees[Employee_ID].Add(day_and_type);
Run Code Online (Sandbox Code Playgroud)

现在我如何取消打开var并访问这些属性?

cas*_*One 13

首先,您不是拆箱类型.匿名类型是引用类型,而不是结构.

即使你可以在技术上创建它们声明的方法之外的相同类型的实例(根据C#3.0语言规范的7.5.10.6节,其中规定:

在同一程序中,两个匿名对象初始值设定项以相同的顺序指定相同名称和编译时类型的属性序列,这将生成相同匿名类型的实例.

)您无法获取所需类型的名称,以便执行从Object回到您创建的类型的转换.您将不得不求助于一个具有内在缺陷的示例解决方案.

逐个示例是有缺陷的,因为从设计的角度来看,您想要在声明的函数外部访问类型的每个地方(并且仍然在同一个模块中),您必须再次有效地声明类型.

这是一种重复的努力,导致设计和实施的草率.

如果您使用的是.NET 4.0,则可以将对象实例放在动态变量中.但是,主要缺点是缺乏成员访问的编译时验证.您可能很容易拼错该成员的名称,然后您有一个运行时错误而不是编译时错误.

最终,如果您发现需要在声明的方法之外使用匿名类型,那么唯一的好方法是创建具体类型并将匿名类型替换为具体类型.


ang*_*son 8

有几种方法.

由于注释似乎表明我建议你这样做,让我说清楚:你应该为你的对象创建一个命名类型,因为你打算传递它.

首先,你可以使用Reflection,这里已经指出了另一个答案.

另一种方法,它将.NET用于提供正确的类型,称为"按示例执行",它是这样的:你需要通过泛型方法调用传递你的对象,它会将对象作为正确的类型返回,通过推断正确的类型返回.

例如,试试这个:

private static T CastByExample<T>(T example, object value)
{
    return (T)value;
}
Run Code Online (Sandbox Code Playgroud)

并使用它:

var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);
Run Code Online (Sandbox Code Playgroud)

这两个?斑点,您只需要传递适合这些属性的数据类型的东西,不会使用这些值.

这利用了以下事实:在同一个程序集中,包含完全相同属性,相同类型,相同顺序的多个匿名类型将映射到同一个单一类型.

但是,此时您应该创建一个命名类型.