c# foreach (свойство в объекте)... есть ли простой способ сделать это?

У меня есть класс, содержащий несколько свойств (все это строки, если это имеет значение).
У меня также есть список, который содержит много разных экземпляров класса.

создавая некоторые модульные тесты для своих классов, я решил, что хочу перебрать каждый объект в списке, а затем перебрать каждое свойство этого объекта...

Я думал, что это будет так же просто, как...

foreach (Object obj in theList)
{
     foreach (Property theProperties in obj)
     {
         do some stufff!!;
     }
}

но это не работает! :( Я понимаю. ошибка...

"оператор foreach не может работать с переменными типа' Application.Объект "потому что" приложение.Объект "не содержит публичного определения для "GetEnumerator""

кто-нибудь знает способ сделать это без тонны ifs и циклов или без попадания во что-то слишком сложное?

7 ответов


попробуйте:

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

Также обратите внимание, что Type.GetProperties() имеет перегрузку, которая принимает набор флагов привязки, поэтому вы можете отфильтровать свойства по другим критериям, таким как уровень доступности, см. MSDN для получения дополнительной информации: тип.Метод GetProperties (BindingFlags) последнее, но не менее не забудьте добавить систему".Отражение " ссылка на сборку.

например, чтобы разрешить все общедоступные свойства:

foreach (var propertyInfo in obj.GetType()
                                .GetProperties(
                                        BindingFlags.Public 
                                        | BindingFlags.Instance))
{
   // do stuff here
}

пожалуйста, дайте мне знать работает ли это так, как ожидалось.


вы можете перебирать все неиндексированные свойства такого объекта:

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 в качестве второго параметра.

возможно, Вам потребуется дополнительно изменить фильтр, чтобы отсеять только для записи и недоступные свойства.


Your'e почти там, вам просто нужно получить свойства от типа, а не ожидать, что свойства будут доступны в виде коллекции или мешка свойств:

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

отсюда вы можете получить доступ как так:

property.Name
property.GetValue(obj, null)

С GetValue второй параметр позволит вам указать значения Индекса, которые будут работать со свойствами, возвращающими коллекции - поскольку строка является коллекцией символов, вы также можете указать индекс для возврата характер, если нужно.


конечно, нет проблем:

foreach(object item in sequence)
{
    if (item == null) continue;
    foreach(PropertyInfo property in item.GetType().GetProperties())
    {
        // do something with the property
    }
}

используйте отражение, чтобы сделать это

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

небольшое предупреждение, если "сделать некоторые вещи" означает обновление значения фактического свойства, которое вы посещаете, и если есть свойство типа структуры по пути от корневого объекта к посещаемому свойству, изменение, внесенное вами в свойство, не будет отражено на корневом объекте.


Я не мог получить любой из вышеперечисленных способов работы, но это сработало. Имя пользователя и пароль для 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;
    }