C# 如何从匿名类型获取属性值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/874746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get a value of a property from an anonymous type?
提问by Sailing Judo
I have a datagrid populated by a Linq query. When the focused row in the datagrid changes I need to set a variable equal to one of the properties in that object.
我有一个由 Linq 查询填充的数据网格。当数据网格中的焦点行发生变化时,我需要设置一个等于该对象中属性之一的变量。
I tried...
我试过...
var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject.Id;
... but the compiler doesn't care for this at all ("Embedded statement cannot be a declaration or labled statement").
...但编译器根本不关心这一点(“嵌入式语句不能是声明或标记的语句”)。
It seems like the property should be easy to access. Inspecting the object during runtime shows all the properties I expect, I just don't know how to access them.
似乎该属性应该很容易访问。在运行时检查对象显示了我期望的所有属性,我只是不知道如何访问它们。
How can I get access to the anonymous object's property?
如何访问匿名对象的属性?
Edit for Clarifications:
编辑澄清:
I happen to be using DevExpress XtraGrid control. I loaded this control with a Linq query which was composed of several different objects, therefore making the data not really conforming with any one class I already have (ie, I cannot cast this to anything).
我碰巧在使用 DevExpress XtraGrid 控件。我用一个由几个不同对象组成的 Linq 查询加载了这个控件,因此使数据与我已经拥有的任何一个类都不符合(即,我不能将它转换为任何东西)。
I'm using .NET 3.5.
我正在使用 .NET 3.5。
When I view the results of the view.GetRow(rowHandle) method I get an anonymous type that looks like this:
当我查看 view.GetRow(rowHandle) 方法的结果时,我得到一个匿名类型,如下所示:
{ ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }
My objective is to get the ClientId from this anonymous type so I can do other things (such as a load a form with that client record in it).
我的目标是从这个匿名类型中获取 ClientId,以便我可以做其他事情(例如加载一个包含该客户记录的表单)。
I tried a couple of the suggestions in the early answers but was unable to get to a point where I could get this ClientId.
我尝试了早期答案中的一些建议,但无法达到可以获取此 ClientId 的程度。
采纳答案by Bigabdoul
Have you ever tried to use reflection? Here's a sample code snippet:
你有没有试过使用反射?这是一个示例代码片段:
// 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...
回答by JaredPar
One of the problems with anonymous types is that it's difficult to use them between functions. There is no way to "name" an anonymous type and hence it's very difficult to cast between them. This prevents them from being used as the type expression for anything that appears in metadata and is user defined.
匿名类型的问题之一是很难在函数之间使用它们。没有办法“命名”匿名类型,因此很难在它们之间进行转换。这可以防止它们被用作元数据中出现的任何用户定义的类型表达式。
I can't tell exactly which API you are using above. However it's not possible for the API to return a strongly typed anonymous type so my guess in that selectedObject is typed to object. C# 3.0 and below does not support dynamic access so you will be unable to access the property Id even if it is available at runtime.
我无法确切地说出您在上面使用的是哪个 API。但是,API 不可能返回强类型匿名类型,因此我猜测 selectedObject 被键入为 object。C# 3.0 及以下版本不支持动态访问,因此您将无法访问属性 Id,即使它在运行时可用。
You will need to one of the following to get around this
您需要执行以下操作之一来解决此问题
- Use reflection to grab the property
- Create a full type and use that to populate the datagrid
- Use one of the many hacky anonymous type casts
- 使用反射来抓取属性
- 创建一个完整的类型并使用它来填充数据网格
- 使用许多 hacky 匿名类型转换之一
EDIT
编辑
Here's a sample on how to do a hack anonymous type cast
这是一个关于如何进行匿名类型转换的示例
public T AnonymousTypeCast<T>(object anonymous, T typeExpression) {
return (T)anonymous;
}
...
object obj = GetSomeAnonymousType();
var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 });
The reason it's hacky is that it's very easy to break this. For example in the method where the anonymous type is originally created. If I add another property to the type there the code above will compile but fail at runtime.
它的原因是它很容易破解。例如在最初创建匿名类型的方法中。如果我向类型中添加另一个属性,上面的代码将编译但在运行时失败。
回答by Kevin Anderson
This may be wrong (you may not have enough code there) but don't you need to index into the row so you choose which column you want? Or if "Id" is the column you want, you should be doing something like this:
这可能是错误的(您可能没有足够的代码)但是您不需要索引到行中以便您选择所需的列吗?或者如果“Id”是你想要的列,你应该做这样的事情:
var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject["Id"];
This is how I'd grab the contents of a column in a datagrid. Now if the column itself is an anonymous type, then I dunno, but if you're just getting a named column with a primitive type, then this should work.
这就是我在数据网格中获取列内容的方式。现在,如果列本身是匿名类型,那么我不知道,但是如果您只是获得具有原始类型的命名列,那么这应该可行。
回答by Sven Künzler
As JaredPar guessed correctly, the return type of GetRow()
is object
. When working with the DevExpress grid, you could extract the desired value like this:
正如 JaredPar 猜对的那样, 的返回类型GetRow()
是object
。使用 DevExpress 网格时,您可以像这样提取所需的值:
int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId");
This approach has similar downsides like the "hacky anonymous type casts" described before: You need a magic string for identifying the column plus a type cast from object to int.
这种方法与之前描述的“hacky 匿名类型转换”有类似的缺点:您需要一个用于标识列的魔术字符串以及从 object 到 int 的类型转换。
回答by Hugoware
When I was working with passing around anonymous types and trying to recast them I ultimately found it easier to write a wrapper that handled working with the object. Here is a link to a blog post about it.
当我处理传递匿名类型并尝试重铸它们时,我最终发现编写一个处理对象工作的包装器更容易。这是一篇关于它的博客文章的链接。
http://somewebguy.wordpress.com/2009/05/29/anonymous-types-round-two/
http://somewebguy.wordpress.com/2009/05/29/anonymous-types-round-two/
Ultimately, your code would look something like this.
最终,您的代码看起来像这样。
//create an anonymous type
var something = new {
name = "Mark",
age = 50
};
AnonymousType type = new AnonymousType(something);
//then access values by their property name and type
type.With((string name, int age) => {
Console.Write("{0} :: {1}", name, age);
});
//or just single values
int value = type.Get<int>("age");
回答by Mike Malter
Hope this helps, am passing in an interface list, which I need to get a distinct list from. First I get an Anonymous type list, and then I walk it to transfer it to my object list.
希望这会有所帮助,我正在传递一个接口列表,我需要从中获取一个不同的列表。首先我得到一个匿名类型列表,然后我遍历它以将它传输到我的对象列表。
private List<StockSymbolResult> GetDistinctSymbolList( List<ICommonFields> l )
{
var DistinctList = (
from a
in l
orderby a.Symbol
select new
{
a.Symbol,
a.StockID
} ).Distinct();
StockSymbolResult ssr;
List<StockSymbolResult> rl = new List<StockSymbolResult>();
foreach ( var i in DistinctList )
{
// Symbol is a string and StockID is an int.
ssr = new StockSymbolResult( i.Symbol, i.StockID );
rl.Add( ssr );
}
return rl;
}
回答by wcm
A generic solution for getting the value of a data item for a given key
获取给定键的数据项值的通用解决方案
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;
}
Example:
例子:
var dataitem = /* Some value here */;
bool ismember = TypeUtils.GetValueFromAnonymousType<bool>(dataitem, "IsMember");
回答by Lasse Skindstad Ebert
You can loop through the properties of an anonymous type like this:
您可以像这样遍历匿名类型的属性:
var obj = new {someValue = "hello", otherValue = "world"};
foreach (var propertyInfo in obj.GetType().GetProperties() {
var name = propertyInfo.Name;
var value = propertyInfo.GetValue(obj, index: null);
...
}
回答by Narayanan
DevExpress's xtraGridView has a method like this GetRowCellDisplayText(int rowHandle, GridColumn column). With this method, the following code returns the id from the anonymous type.
DevExpress 的 xtraGridView 有一个这样的方法 GetRowCellDisplayText(int rowHandle, GridColumn column)。使用此方法,以下代码从匿名类型返回 id。
var _selectedId = view.GetRowCellDisplayText(rowHandle, "Id");
Though this does not provide an answer to the question "How can I get access to the anonymous object's property?", it still attempts to solve the root cause of the problem.
虽然这并没有回答“我如何才能访问匿名对象的属性?”的问题,但它仍然试图解决问题的根本原因。
I tried this with devXpress version 11.1 and I can see that the question was first asked almost 2.5 years ago. Possibly the author of the question might have got an workaround or found the solution himself. Yet, I am still answering so that it might help someone.
我在 devXpress 11.1 版中尝试过这个,我可以看到这个问题是在大约 2.5 年前首次提出的。可能问题的作者可能已经找到了解决方法或自己找到了解决方案。然而,我仍在回答,以便它可以帮助某人。
回答by Per
You could use the dynamic type to access properties of anonymous types at runtime without using reflection.
您可以使用动态类型在运行时访问匿名类型的属性,而无需使用反射。
var aType = new { id = 1, name = "Hello World!" };
//...
//...
dynamic x = aType;
Console.WriteLine(x.name); // Produces: Hello World!
Read more about dynamic type here: http://msdn.microsoft.com/en-us/library/dd264736.aspx
在此处阅读有关动态类型的更多信息:http: //msdn.microsoft.com/en-us/library/dd264736.aspx