在List <t>中搜索对象的所有公共变量以获取特定字符串</t>

时间:2013-10-18 14:10:54

标签: c# .net linq reflection

我正在尝试查看是否可以使用Linq搜索具有任何给定对象的.ToString()方法的所有公共变量。

基本上我想提供两个参数,一个List<T>来搜索一个string并返回List<T>个包含一个或多个包含我的字符串的公共变量的对象。< / p>

我可以使用

获取对象的所有公共属性
Type objectType = _data[0].GetType();
var properties = objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
var fields = objectType.GetFields(BindingFlags.Public | BindingFlags.Instance)

但我仍然坚持如何使用它来搜索对象列表而不会遍历所有对象及其所有属性。

2 个答案:

答案 0 :(得分:5)

这是一个完整的例子:

(注意:我会编辑此答案以考虑ToString()覆盖)

编辑:完成

public class Program
{
    public class ToStringNotOverrided0 { }
    public int Int { get; set; }
    public string str;
    public ToStringNotOverrided0 toStringNotOverrided;

    public static IEnumerable<T> getMatches<T>(List<T> list, string search) {
        if (search == null)
            throw new ArgumentNullException("search");
        return list.Select(x => new
        {
            X = x,
            Props = x.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public),
            Fields = x.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public),
        })
        .Where(x => x.Props.Any(p =>
                            {
                                var val = p.GetValue(x.X, null);
                                return val != null
                                    && val.GetType().GetMethod("ToString", Type.EmptyTypes).DeclaringType == val.GetType()
                                    && val.ToString().Contains(search);
                            })
                    || x.Fields.Any(p =>
                            {
                                var val = p.GetValue(x.X);
                                return val != null
                                    && val.GetType().GetMethod("ToString", Type.EmptyTypes).DeclaringType == val.GetType()
                                    && val.ToString().Contains(search);
                            }))
        .Select(x => x.X);
    }

    static void Main(string[] args)
    {
        List<Program> list = new List<Program>{
            new Program { Int = 0, str = "foo bar" , toStringNotOverrided = new ToStringNotOverrided0()},
            new Program { Int = 54, str = "foo 0 bar"  , toStringNotOverrided = new ToStringNotOverrided0()},
            new Program { Int = 12, str = "foo bar"  , toStringNotOverrided = new ToStringNotOverrided0()},
            new Program { Int = 720, str = "foo bar" , toStringNotOverrided = new ToStringNotOverrided0() }
        };
        foreach (var item in getMatches(list, "0"))
        {
            Debug.WriteLine("Int = " + item.Int 
                + ", str = " + item.str
                + ", toStringNotOverrided = " + item.toStringNotOverrided);
        }
    }
}

答案 1 :(得分:0)

var type = objectToCheck.GetType();
bool isMethodExist = type.GetMethod(methodName) != null;

如果您有List<T>

var type = _data.GetType().GetGenericArguments()[0];
bool isMethodExist = type.GetMethod(methodName) != null;