C # Список FindAll с отражением - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть структура с большим количеством членов.Мне нужно отфильтровать сетку.Теперь у меня есть что-то вроде этого:

foreach(string word in words)
{
    if (c.Caption == "ID") 
        FilteredList.AddRange(BaseList.FindAll(x => x.ID == Int32.Parse(word)));
    else if (c.Caption == "Serial"
        FilteredList.AddRange(BaseList.FindAll(x => x.Serial == word));
    else if (c.Caption == "Phone")
        FilteredList.AddRange(BaseList.FindAll(x => x.Phone == word));
    etc...
}

Возможно ли создать что-то подобное?

 foreach(string word in words)
 {
     var propertyInfo = object.GetType().GetMember(word);
     FilteredList.AddRange(BaseList.FindAll(x => x.propertyInfo == word));    
 }

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Отражение здесь не совсем работает, потому что у вас есть особый случай - ID.Если c.Caption равно ID, вы бы позвонили int.Parse перед сравнением.Это делает непосредственное использование отражения довольно трудным.

Если этот особый случай не существует, и у вас есть только string свойства для сравнения, то вы можете сделать это:

 foreach(string word in words)
 {
     var propertyInfo = object.GetType().GetProperty(word);
     FilteredList.AddRange(BaseList.FindAll(x => propertyInfo.GetValue(x) == word));    
 }

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

public bool CustomEquals(object o1, object o2) {
    if (o1 is int && o2 is string) {
        return o1 == int.Parse((string)o2);
    }
    // handle other special cases here...
    return o1 == o2;
}

// usage:
FilteredList.AddRange(BaseList.FindAll(x => CustomEquals(propertyInfo.GetValue(x), word)));
0 голосов
/ 06 декабря 2018

Предполагая, что BaseList - это универсальная коллекция , объявленная как

  // Any collection with 1st Generic type being item's type
  List<SomeClass> BaseList = ...

Мы можем искать свойство:

  using System.Linq;
  using System.Reflection;

  ...

  var property = BaseList      // Given a collection...
    .GetType()
    .GetGenericArguments()[0]  // Get collection's item type 
    .GetProperties()
    .Where(prop => 
        prop.CanRead &&                  // readable  
       !prop.GetGetMethod().IsStatic &&  // not static
        prop.GetGetMethod().IsPublic &&  // public
       (typeof(IConvertible)).IsAssignableFrom(prop.PropertyType)) // convertable
    .FirstOrDefault(prop => string.Equals(prop.Name, c.Caption));  // of given name 

И затем читать *Значение 1010 * s и сравните его с преобразованным word:

  if (property != null) {
    foreach(string word in words) {
      FilteredList.AddRange(BaseList.FindAll(item => 
        // convert given string (word) to property value's type
        // and compare
        object.Equals(Convert.ChangeType(word, property.PropertyType), 
                      property.GetValue(item)))); 
  }
  else {
    // Property not found
  }
0 голосов
/ 06 декабря 2018

Я думаю, что это должно быть примерно так:

foreach(string word in words)
{
    var propertyInfo = object.GetType().GetMember(word);
    FilteredList.AddRange(BaseList.FindAll(x => propertyInfo.GetValue(x) == word));    
}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...