C#使用反射列出FindAll

时间:2018-12-06 09:45:49

标签: c# list reflection

我有很多成员的结构。我需要过滤网格。 现在我有这样的东西:

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 :(得分:0)

我认为应该是这样的:

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

希望有帮助!

答案 1 :(得分:0)

反射在这里不太起作用,因为您有一个特殊情况-$rootScope.$on('$routeChangeStart' ... 。如果IDc.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));    
 }

答案 2 :(得分:0)

假设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 

然后读取property的值,并将其与转换后的 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
  }