匿名类型

发布于 2024-08-23 00:48:15 字数 502 浏览 14 评论 0原文

我有一个 字典(TKey, TValue) 就像

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 的装箱并访问这些属性?

I have a Dictionary(TKey, TValue) like

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 ??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

败给现实 2024-08-30 00:48:15

首先,您没有拆箱该类型。匿名类型是引用类型,而不是结构。

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

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

)您无法获取类型的名称,而您需要该名称才能将Object强制转换回您创建的类型。您将不得不求助于本质上有缺陷的 逐例转换解决方案

按示例进行转换是有缺陷的,因为从设计的角度来看,您想要访问声明的函数外部的类型(并且仍在同一模块内)的每个地方,您都必须有效地重新声明该类型。

这是重复的工作,导致草率的设计和实施。

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

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

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:

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. 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. 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.

幻想少年梦 2024-08-30 00:48:15

有几种方法。

由于评论似乎表明我建议您这样做,所以让我说清楚:您应该为您的对象创建一个命名类型,因为您打算传递它。

首先,您可以使用反射,这里的另一个答案已经指出了。

另一种欺骗 .NET 为您提供正确类型的方法称为“通过示例进行转换”,其过程如下:您需要通过通用方法调用传递对象,该方法将返回正确类型的对象,通过推断要返回的正确类型。

例如,尝试这个:

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

并使用它:

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

对于两个 ??点,您只需要传递一些适合这些属性的数据类型的东西,这些值将不会被使用。

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

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

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.

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.

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.

最冷一天 2024-08-30 00:48:15

匿名类型具有方法范围。要在方法边界之外传递匿名类型或包含匿名类型的集合,必须首先将该类型强制转换为对象。然而,这破坏了匿名类型的强类型。如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类,而不是匿名类型。

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

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

泡沫很甜 2024-08-30 00:48:15

不,你不能。您只能使用反射来访问属性。编译器无法知道类型是什么,并且由于它是匿名类型,因此您也无法对其进行强制转换。

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.

海的爱人是光 2024-08-30 00:48:15

如果您使用 .NET 1.x - 3.x,则必须使用反射。

如果您使用 .NET 4.0,则可以使用动态类型并调用预期的属性。

在这两种情况下,您都不需要拆箱;这是针对值类型的。匿名类型始终是引用类型。

If you are using .NET 1.x - 3.x, you must use reflection.

If you use .NET 4.0, you could use a dynamic type and call the expected properties.

In neither case do you need to unbox; that's for value types. Anonymous types are always reference types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文