关于属性:c#foreach(对象中的属性)…有一种简单的方法吗?

c# foreach (property in object)… Is there a simple way of doing this?

我有一个包含几个属性的类(如果有任何不同,所有属性都是字符串)。我还有一个列表,其中包含了该类的许多不同实例。

在为类创建一些单元测试时,我决定遍历列表中的每个对象,然后遍历该对象的每个属性…

我想这样做就像…

1
2
3
4
5
6
7
foreach (Object obj in theList)
{
     foreach (Property theProperties in obj)
     {
         do some stufff!!;
     }
}

但这没用!:(我得到这个错误…

"foreach语句无法对类型为"application.object"的变量进行操作,因为"application.object"不包含"getEnumerator"的公共定义。"

有人知道这样做的方法吗?没有大量的if和循环,或者没有陷入任何太复杂的事情中?


尝试一下:

1
2
3
4
foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
   // do stuff here
}

另外,请注意,Type.GetProperties()有一个重载,它接受一组绑定标志,因此您可以筛选出其他条件(如可访问性级别)上的属性,有关更多详细信息,请参阅msdn:type.getproperties method(bindingFlags)last,但至少不要忘记添加"system.reflection"程序集引用。

例如,要解析所有公共属性:

1
2
3
4
5
6
7
foreach (var propertyInfo in obj.GetType()
                                .GetProperties(
                                        BindingFlags.Public
                                        | BindingFlags.Instance))
{
   // do stuff here
}

请告诉我这是否按预期工作。


您可以这样循环访问对象的所有非索引属性:

1
2
3
4
var s = new MyObject();
foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) {
    Console.WriteLine(p.GetValue(s, null));
}

由于GetProperties()返回索引器和简单属性,因此在调用GetValue之前需要一个额外的过滤器,以知道将null作为第二个参数传递是安全的。

您可能需要进一步修改过滤器,以消除只写和不可访问的属性。


就在这里,您只需要从类型中获取属性,而不是期望属性可以以集合或属性包的形式访问:

1
var property in obj.GetType().GetProperties()

从那里你可以这样访问:

1
2
property.Name
property.GetValue(obj, null)

使用GetValue,第二个参数将允许您指定索引值,该值将与返回集合的属性一起使用-由于字符串是字符的集合,因此如果需要,您还可以指定一个索引来返回字符。


当然,没问题:

1
2
3
4
5
6
7
8
foreach(object item in sequence)
{
    if (item == null) continue;
    foreach(PropertyInfo property in item.GetType().GetProperties())
    {
        // do something with the property
    }
}


使用反射进行此操作

1
2
SomeClass A = SomeClass(...)
PropertyInfo[] properties = A.GetType().GetProperties();

我不能用上述任何一种方式工作,但这是可行的。DirectoryEntry的用户名和密码是可选的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   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;
    }


注意:如果"做一些事情"意味着更新您访问的实际属性的值,并且如果在从根对象到访问的属性的路径上有一个struct-type属性,则对该属性所做的更改不会反映在根对象上。