简体   繁体   English

匿名类型

[英]Anonymous Types

I have a Dictionary(TKey, TValue) like 我有一个Dictionary(TKey, TValue)类的

Dictionary<int, ArrayList> Deduction_Employees = 
    new Dictionary<int, ArrayList>();

and later I add to that array list an anonymous type like this 后来我在这个数组列表中添加了这样的匿名类型

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

Deduction_Employees[Employee_ID].Add(day_and_type);

Now how can I unbox that var and access those properties ?? 现在我如何取消打开var并访问这些属性?

First, you aren't unboxing the type. 首先,您不是拆箱类型。 Anonymous types are reference types, not structures. 匿名类型是引用类型,而不是结构。

Even though you can technically create instances of the same type outside of the method they were declared in (as per section 7.5.10.6 of the C# 3.0 Language Specification, which states: 即使你可以在技术上创建它们声明的方法之外的相同类型的实例(根据C#3.0语言规范的7.5.10.6节,其中规定:

Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type. 在同一程序中,两个匿名对象初始值设定项以相同的顺序指定相同名称和编译时类型的属性序列,这将生成相同匿名类型的实例。

) you have no way of getting the name of the type, which you need in order to perform the cast from Object back to the type you created. )您无法获取类型的名称 ,以便从Object执行转换回您创建的类型。 You would have to resort to a cast-by-example solution which is inherently flawed. 您将不得不求助于一个具有内在缺陷的示例解决方案

Cast-by-example is flawed because from a design standpoint, every single place you want to access the type outside the function it is declared (and still inside the same module), you have to effectively declare the type all over again. 逐个示例是有缺陷的,因为从设计的角度来看,您想要在声明的函数外部访问类型的每个地方(并且仍然在同一个模块中),您必须再次有效地声明类型。

It's a duplication of effort that leads to sloppy design and implementation. 这是一种重复的努力,导致设计和实施的草率。

If you are using .NET 4.0, then you could place the object instance in a dynamic variable. 如果您使用的是.NET 4.0,则可以将对象实例放在动态变量中。 However, the major drawback is the lack of compile-time verification of member access. 但是,主要缺点是缺乏成员访问的编译时验证。 You could easily misspell the name of the member, and then you have a run-time error instead of a compile-time error. 您可能很容易拼错该成员的名称,然后您有一个运行时错误而不是编译时错误。

Ultimately, if you find the need to use an anonymous type outside the method it is declared in, then the only good solution is to create a concrete type and substitute the anonymous type for the concrete type. 最终, 如果您发现需要在声明的方法之外使用匿名类型,那么唯一的好方法是创建具体类型并将匿名类型替换为具体类型。

There are several ways. 有几种方法。

Since the comments seems to indicate that I suggest you do this, let me make it clear: You should be creating a named type for your object since you intend to pass it around. 由于注释似乎表明我建议你这样做,让我说清楚: 你应该为你的对象创建一个命名类型,因为你打算传递它。

First, you can use Reflection, which another answer here has already pointed out. 首先,你可以使用Reflection,这里已经指出了另一个答案。

Another way, which tricks .NET into giving you the right type is known as "cast by example", and it goes something like this: You need to pass your object through a generic method call, which will return the object as the right type, by inferring the right type to return. 另一种方法,它将.NET用于提供正确的类型,称为“按示例执行”,它是这样的:你需要通过泛型方法调用传递你的对象,它会将对象作为正确的类型返回,通过推断正确的类型返回。

For instance, try this: 例如,试试这个:

private static T CastByExample<T>(T example, object value)
{
    return (T)value;
}

and to use it: 并使用它:

var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);

for the two ?? 这两个? spots, you just need to pass something fitting the data type for those properties, the values will not be used. 斑点,您只需要传递适合这些属性的数据类型的东西,不会使用这些值。

This exploits the fact that multiple anonymous types containing the exact same properties, of the same type, in the same order, in the same assembly, will map to the same single type. 这利用了以下事实:在同一个程序集中,包含完全相同属性,相同类型,相同顺序的多个匿名类型将映射到同一个单一类型。

However, by this time you should be creating a named type instead. 但是,此时您应该创建一个命名类型。

An anonymous type has method scope. 匿名类型具有方法范围。 To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. 要在方法边界外传递匿名类型或包含匿名类型的集合,必须先将类型转换为对象。 However, this defeats the strong typing of the anonymous type. 然而,这打败了匿名类型的强类型。 If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type. 如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类而不是匿名类型。

Source: http://msdn.microsoft.com/en-us/library/bb397696.aspx 来源: http//msdn.microsoft.com/en-us/library/bb397696.aspx

No you can't. 不,你不能。 You can only access the properties by using reflection. 您只能使用反射访问属性。 The compiler has no way of knowing what the type was, and since it's an anonymous type, you can't cast it either. 编译器无法知道类型是什么,并且由于它是匿名类型,因此您也无法对其进行转换。

If you are using .NET 1.x - 3.x, you must use reflection. 如果您使用的是.NET 1.x - 3.x,则必须使用反射。

If you use .NET 4.0, you could use a dynamic type and call the expected properties. 如果使用.NET 4.0,则可以使用动态类型并调用预期的属性。

In neither case do you need to unbox; 在这两种情况下你都不需要拆箱; that's for value types. 这是价值类型。 Anonymous types are always reference types. 匿名类型始终是引用类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM