LINQ,Visual Basic,&反射:从返回匿名类型的查询中大写字段名称

时间:2014-01-14 17:34:58

标签: vb.net linq visual-studio reflection capitalization

编辑回答我自己的问题。这似乎是一个LINQ / VB错误。

返回anomymous类型的简单LINQ查询有时会更改查询中指定的字段名称,以便将它们大写。也许将查询结果作为参数传递给方法调用:

someThing.someMethod(From someStuff In stuffList _
                     Select text = someStuff.Name(), _
                            value = someStuff.Id
                     )

其中someMethod有签名

Public Sub someMethod(ByVal list As IEnumerable(Of Object))

如果您单步执行someMethod,然后在quickwatch中检查list的值,您可能会看到字段名称为“text”&“value”或“Text” &安培; “值”

LINQ查询不应该更改查询中指定的字段名称,因此正确的行为是字段名“text”&“value”。然而,我们的应用程序的生成版本具有不正确的大写行为(可以间接确定),并且调试版本已经表明它在不同时间和/或不同开发人员的机器上都会发生。

我看起来很高兴对于控制此行为的LINQ的某些功能来说很低,但现在几乎可以肯定它是一个错误。 (msdn forum threadMS Connect bug page

如果您使用反射,这可能只会导致问题,例如<{p>}中的type.getfield()

listItem = list.ElementAt(index)
itemTextField = listItem.GetType().GetField("text")
itemText = CType(itemTextField.GetValue(listItem),String)

如果您遇到这种情况,解决方法是使用带有绑定标志的GetField重载来使其不区分大小写:

itemTextField = listItem.GetType().GetField("text", BindingFlags.IgnoreCase)

遇到这个错误一定很少见,但如果他们在这里找到这些信息,下一个人可能会花更少的时间挠头。

=========原帖=========== 在我的调试构建环境中获得与我的同事和我们的生产环境中不同的行为,与LINQ和反射相关......

在运行遗留代码的调试版本时,使用以下代码

    Dim objectType As Type = obj.GetType()
    Dim field As FieldInfo = objectType.GetField(name)
    Dim prop As PropertyInfo = objectType.GetProperty(name)

Nothingfield生成prop obj

From bpt In CustomBProcessTypes Select text = bpt.Name(), value = bpt.Id 的值从上面传递下来,是LINQ查询的结果(它是查询生成的列表的单个元素):

name

obj的值也从上面传递,并且是“Text”(注意大写)。 我可以在调试器中检查{{1}}并确认LINQ查询创建的对象的字段名是'text'和'value'(注意缺少大小写),这正是我所期望的。

因此,无法通过大写名称找到该字段是有道理的。但是,我们的生产构建和我的同事构建没有这个问题。

因为对type.getfield(string)的调用明显是cas-sensitive,所以我在这一点上唯一能想到的就是必须有一些LINQ配置与列/字段名的自动大写相关,我的环境是与其他人没有相同的设置。

使用visual studio 2012.我对LINQ本身一无所知。

任何人都知道这里会发生什么?

(注意:如果我有机会,我会让同事逐步完成相关代码,看看在他们的环境中,linq查询创建的对象是否以大写字段名称结束)

编辑:我在他的调试版本中与同事验证:他的LINQ查询创建了一个字段名称为“Text”和“Value”的对象列表,但在我的环境中,LINQ查询以字段名称“text”结束和“价值”。代码是相同的,但必须有一些关于如何在我的环境中配置LINQ的内容,这些LINQ无法自动大写这些字段名称,但这些名称在他们的机器和生产环境中发生。

2 个答案:

答案 0 :(得分:0)

我认为某些编译器设置可能导致不同的大小写。通常这没有区别,因为VB.NET是一种不区分大小写的语言,因此obj.Textobj.text都可以正常工作。但是要在反射查找中使用不区分大小写,您需要通过在BindingFlags.IgnoreCaseGetField的第二个参数中包含GetProperty来指定它:

Dim field As FieldInfo = objectType.GetField(name,
    BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.IgnoreCase)
但是,我对name来自哪里感到困惑。其他一些代码是从查询的反射中获取字段名称?我没有看到你的问题在哪里解释过。

答案 1 :(得分:0)

我已回答了我自己的问题(尽可能)。归结为LINQ / vb.net中的一个错误。

在原始帖子(编辑)的顶部完全解释。希望这能节省一些时间。