1

我是Reflection的新手,所以请原谅我的菜鸟问题。如何创建一个采用两个参数、一个通用列表和一个字符串的方法,然后在该列表中找到任何属性值与字符串匹配的所有项目。

例如,我们有一个具有 3 个属性的对象,我将这个对象的列表传递给方法和一个搜索字符串,然后它返回一个对象列表,其中任何属性都可能包含搜索字符串。

我可以这样做:

var temp = list.AsQueryable().Where("SomeField == 1").Select("it");

但是我怎样才能使这个方法通用,以便我可以将任何对象列表传递给它?

提前致谢...

4

5 回答 5

1

用于Type.GetProperties()获取对象的所有属性。用于PropertyInfo.GetValue()获取给定对象中给定属性的值。您需要弄清楚如何将字符串与 DateTime、数字或其他复杂对象进行匹配。将其全部放入一个函数中,例如bool IsMatch(this object obj, string val). 然后您可以过滤您的列表,例如list.Where(x => x.IsMatch("something")).

于 2013-12-13T15:17:57.373 回答
1

来了,伙计:

    private static void Main(string[] args)
    {
        var list = new List<object> {new {prop1 = "A", prop2 = "B"},new {prop3 = "B", prop4 = "C"}};
        var subList = SearchForStringInProperties(list, "C");
    }

    private static IEnumerable<object> SearchForStringInProperties(IEnumerable<object> list, string searchString)
    {
        return from obj in list where FindStringInObjProperties(obj, searchString) select obj;
    }

    private static bool FindStringInObjProperties(object obj, string searchString)
    {
        return obj.GetType().GetProperties().Any(property => obj.GetType().GetProperty(property.Name).GetValue(obj).ToString().Equals(searchString));
    }
于 2013-12-13T15:32:11.330 回答
1

如果您使用的是 Dynamic Linq,试试这个

public static IEnumerable<T> Filter<T>(IEnumerable<T> source, string searchStr)
{
    var propsToCheck = typeof (T).GetProperties().Where(a => a.PropertyType == typeof(string));

    var filter = propsToCheck.Aggregate(string.Empty, (s, p) => (s == string.Empty ? string.Empty : string.Format("{0} OR ", s)) + string.Format("{0} == @0", p.Name));

    var filtered = source.AsQueryable().Where(filter, searchStr);
    return filtered;
}
于 2013-12-13T15:41:17.607 回答
0

如果您只想匹配与参数类型相同的属性,此扩展方法可以提供帮助,

 public static class ListExtensions
{
    public static IEnumerable<T> MatchWithAnyProperty<T, TK>(this IEnumerable<T> list, TK value)
    {
        var argType = typeof (TK);
        var properties = typeof(T).GetProperties().Where(x => x.PropertyType.IsAssignableFrom(argType));

      return  list.Where(item => properties.Any(prop =>
            {
                var propertyValue = prop.GetValue(item, null);
                if (value == null)
                    return propertyValue == null;
                return propertyValue.Equals(value);
            }));
    }
}

这可以像这样使用,

var items = new[]
            {
                new
                    {
                        Name = "Test",
                        Age = 20,
                        Test=25
                    },
                new
                    {
                        Name = "Hello",
                        Age = 10,
                        Test=15
                    },
                new
                    {
                        Name = "T2gdhest",
                        Age = 14,
                        Test=20
                    },
                new
                    {
                        Name = "hai",
                        Age = 33,
                        Test=10
                    },
                new
                    {
                        Name = "why not",
                        Age = 10,
                        Test=33
                    },
            };

       var match= items.MatchWithAnyProperty(10);

        foreach (var item in match)
        {
            Console.WriteLine(item.Name);
        }
        Console.ReadKey();
于 2013-12-13T15:34:41.483 回答
0

还有老办法……

    public static IList<T> MyMethod<T>(IList<T> myList, string filter)
    {
        if (myList == null) return null;
        if (filter == null) return myList;

        var tfilter = filter.GetType();
        var properties = typeof(T).GetProperties().Where(x => x.PropertyType.FullName == typeof(string).FullName);
        if (!properties.Any()) return null;


        var res = new List<T>();

        foreach(var el in myList)
        {
            foreach(var p in properties)
            {
                if ((string)p.GetValue(el) == filter)
                {
                    res.Add(el);
                    break;
                }
            }
        }
        return res;
    }
于 2013-12-13T15:50:37.820 回答