c# foreach (property in object)... 有没有一种简单的方法可以做到这一点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9893028/
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
c# foreach (property in object)... Is there a simple way of doing this?
提问by Jammerz858
I have a class containing several properties (all are strings if it makes any difference).
I also have a list, which contains many different instances of the class.
我有一个包含多个属性的类(如果有任何区别,所有属性都是字符串)。
我还有一个列表,其中包含该类的许多不同实例。
While creating some unit tests for my classes I decided I wanted to loop through each object in the list and then loop through each property of that object...
在为我的类创建一些单元测试时,我决定遍历列表中的每个对象,然后遍历该对象的每个属性...
I thought doing this would be as simple as...
我以为这样做会很简单......
foreach (Object obj in theList)
{
foreach (Property theProperties in obj)
{
do some stufff!!;
}
}
But this didnt work! :( I get this error...
但这没有用!:( 我收到此错误...
"foreach statement cannot operate on variables of type 'Application.Object' because 'Application.Object' does not contain a public definition for 'GetEnumerator'"
“foreach 语句不能对‘Application.Object’类型的变量进行操作,因为‘Application.Object’不包含‘GetEnumerator’的公共定义”
Does anyone know of a way of doing this without tons of ifs and loops or without getting into anything too complex?
有没有人知道没有大量的 ifs 和循环或者没有进入任何太复杂的东西的方法?
采纳答案by sll
Give this a try:
试试这个:
foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
// do stuff here
}
Also please note that Type.GetProperties()has an overload which accepts a set of binding flags so you can filter out properties on a different criteria like accessibility level, see MSDN for more details: Type.GetProperties Method (BindingFlags)Last but not least don't forget to add the "system.Reflection" assembly reference.
另请注意,它Type.GetProperties()有一个接受一组绑定标志的重载,因此您可以根据不同的标准(如可访问性级别)过滤掉属性,有关更多详细信息,请参阅 MSDN:Type.GetProperties Method (BindingFlags)最后但并非最不重要的是不要忘记添加“system.Reflection”程序集引用。
For instance to resolve all public properties:
例如解析所有公共属性:
foreach (var propertyInfo in obj.GetType()
.GetProperties(
BindingFlags.Public
| BindingFlags.Instance))
{
// do stuff here
}
Please let me know whether this works as expected.
请让我知道这是否按预期工作。
回答by Arion
Use Reflection to do this
使用反射来做到这一点
SomeClass A = SomeClass(...)
PropertyInfo[] properties = A.GetType().GetProperties();
回答by Grant Thomas
Your'e almost there, you just need to get the properties from the type, rather than expect the properties to be accessible in the form of a collection or property bag:
你快到了,你只需要从类型中获取属性,而不是期望可以以集合或属性包的形式访问这些属性:
var property in obj.GetType().GetProperties()
From there you can access like so:
从那里你可以像这样访问:
property.Name
property.GetValue(obj, null)
With GetValuethe second parameter will allow you to specify index values, which will work with properties returning collections - since a string is a collection of chars, you can also specify an index to return a character if needs be.
使用GetValue第二个参数将允许您指定索引值,这将与返回集合的属性一起使用 - 由于字符串是字符的集合,如果需要,您还可以指定一个索引来返回一个字符。
回答by Eric Lippert
Sure, no problem:
好没问题:
foreach(object item in sequence)
{
if (item == null) continue;
foreach(PropertyInfo property in item.GetType().GetProperties())
{
// do something with the property
}
}
回答by dasblinkenlight
You can loop through all non-indexed properties of an object like this:
您可以循环遍历对象的所有非索引属性,如下所示:
var s = new MyObject();
foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) {
Console.WriteLine(p.GetValue(s, null));
}
Since GetProperties()returns indexersas well as simple properties, you need an additional filter before calling GetValueto know that it is safe to pass nullas the second parameter.
由于GetProperties()返回索引器以及简单的属性,因此在调用之前您需要一个额外的过滤器,GetValue以了解null作为第二个参数传递是安全的。
You may need to modify the filter further in order to weed out write-only and otherwise inaccessible properties.
您可能需要进一步修改过滤器以清除只写和其他无法访问的属性。
回答by Dogu Arslan
A small word of caution, if "do some stuff" means updating the value of the actual property that you visit AND if there is a struct type property along the path from root object to the visited property, the change you made on the property will not be reflected on the root object.
一个小小的警告,如果“做一些事情”意味着更新您访问的实际属性的值,并且如果从根对象到访问属性的路径上有一个结构类型的属性,那么您对属性所做的更改将不会反映在根对象上。
回答by Bbb
I couldn't get any of the above ways to work, but this worked. The username and password for DirectoryEntry are optional.
我无法获得上述任何一种工作方式,但这有效。DirectoryEntry 的用户名和密码是可选的。
private List<string> getAnyDirectoryEntryPropertyValue(string userPrincipalName, string propertyToSearchFor)
{
List<string> returnValue = new List<string>();
try
{
int index = userPrincipalName.IndexOf("@");
string originatingServer = userPrincipalName.Remove(0, index + 1);
string path = "LDAP://" + originatingServer; //+ @"/" + distinguishedName;
DirectoryEntry objRootDSE = new DirectoryEntry(path, PSUsername, PSPassword);
var objSearcher = new System.DirectoryServices.DirectorySearcher(objRootDSE);
objSearcher.Filter = string.Format("(&(UserPrincipalName={0}))", userPrincipalName);
SearchResultCollection properties = objSearcher.FindAll();
ResultPropertyValueCollection resPropertyCollection = properties[0].Properties[propertyToSearchFor];
foreach (string resProperty in resPropertyCollection)
{
returnValue.Add(resProperty);
}
}
catch (Exception ex)
{
returnValue.Add(ex.Message);
throw;
}
return returnValue;
}
回答by Zar Shardan
A copy-paste solution (extension methods) mostly based on earlier responses to this question.
复制粘贴解决方案(扩展方法)主要基于对这个问题的早期回答。
Also properly handles IDicitonary (ExpandoObject/dynamic) which is often needed when dealing with this reflected stuff.
还可以正确处理 IDicitonary (ExpandoObject/dynamic),这在处理这种反射的东西时经常需要。
Not recommended for use in tight loops and other hot paths. In those cases you're gonna need some caching/IL emit/expression tree compilation.
不建议在紧密环路和其他热路径中使用。在这些情况下,您将需要一些缓存/IL 发射/表达式树编译。
public static IEnumerable<(string Name, object Value)> GetProperties(this object src)
{
if (src is IDictionary<string, object> dictionary)
{
return dictionary.Select(x => (x.Key, x.Value));
}
return src.GetObjectProperties().Select(x => (x.Name, x.GetValue(src)));
}
public static IEnumerable<PropertyInfo> GetObjectProperties(this object src)
{
return src.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => !p.GetGetMethod().GetParameters().Any());
}

