如何从匿名类型获取属性的值?

Sai*_*udo 20 .net c# anonymous-types

我有一个由Linq查询填充的数据网格.当datagrid中的焦点行发生更改时,我需要设置一个等于该对象中某个属性的变量.

我试过了...

var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject.Id;
Run Code Online (Sandbox Code Playgroud)

...但编译器根本不关心这个("嵌入式语句不能是声明或标注语句").

看起来这个属性应该很容易访问.在运行时检查对象会显示我期望的所有属性,我只是不知道如何访问它们.

如何访问匿名对象的属性?

编辑澄清:

我碰巧使用DevExpress XtraGrid控件.我用Linq查询加载了这个控件,该查询由几个不同的对象组成,因此使得数据不符合我已经拥有的任何一个类(即,我无法将其转换为任何类).

我正在使用.NET 3.5.

当我查看view.GetRow(rowHandle)方法的结果时,我得到一个如下所示的匿名类型:

{ ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }
Run Code Online (Sandbox Code Playgroud)

我的目标是从这个匿名类型获取ClientId,以便我可以做其他事情(例如在其中加载具有该客户端记录的表单).

我在早期的答案中尝试了一些建议,但无法达到我可以获得此ClientId的程度.

小智 47

你有没有试过用反射?这是一个示例代码段:

// use reflection to retrieve the values of the following anonymous type
var obj = new { ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }; 
System.Type type = obj.GetType(); 
int clientid = (int)type.GetProperty("ClientId").GetValue(obj, null);
string clientname = (string)type.GetProperty("ClientName").GetValue(obj, null);

// use the retrieved values for whatever you want...
Run Code Online (Sandbox Code Playgroud)


小智 20

获取给定键的数据项值的通用解决方案

public static T GetValueFromAnonymousType<T>( object dataitem, string itemkey ) {
    System.Type type = dataitem.GetType();
    T itemvalue = (T)type.GetProperty(itemkey).GetValue(dataitem, null);
    return itemvalue;
}
Run Code Online (Sandbox Code Playgroud)

例:

var dataitem = /* Some value here */;
bool ismember = TypeUtils.GetValueFromAnonymousType<bool>(dataitem, "IsMember");
Run Code Online (Sandbox Code Playgroud)


Jar*_*Par 17

匿名类型的一个问题是在函数之间很难使用它们.没有办法"命名"匿名类型,因此在它们之间进行转换非常困难.这可以防止它们被用作元数据中出现的任何类型的类型表达式,并且是用户定义的.

我无法确切地说出您正在使用的API.但是,API不可能返回强类型的匿名类型,因此我对该对象的猜测是对象的类型.C#3.0及更低版本不支持动态访问,因此即使在运行时可用,您也无法访问属性Id.

您将需要以下其中一项来解决这个问题

  • 使用反射来抓住财产
  • 创建一个完整类型并使用它来填充数据网格
  • 使用众多hacky匿名类型转换之一

编辑

这是一个关于如何进行黑客匿名类型转换的示例

public T AnonymousTypeCast<T>(object anonymous, T typeExpression) { 
  return (T)anonymous;
}

...
object obj = GetSomeAnonymousType();
var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 });
Run Code Online (Sandbox Code Playgroud)

它的hacky的原因是它很容易打破这个.例如,在最初创建匿名类型的方法中.如果我在该类型中添加另一个属性,则上面的代码将编译但在运行时失败.


Per*_*Per 14

您可以使用动态类型在运行时访问匿名类型的属性,而无需使用反射.

var aType = new { id = 1, name = "Hello World!" };
//...
//...
dynamic x = aType;
Console.WriteLine(x.name); // Produces: Hello World!
Run Code Online (Sandbox Code Playgroud)

在此处阅读有关动态类型的更多信息:http://msdn.microsoft.com/en-us/library/dd264736.aspx