是否可以动态设置条件的属性?

时间:2014-12-24 20:11:29

标签: c#

通常,当我想要查找List的第一个或默认项时,我会这样使用:

myList.SingleOrDefault(x=>x.MyPropery01 == "myCondition");

但是,我想知道是否有可能,例如通过反射,如果我动态设置属性MyProperty,如下所示:

myList.SingleOrDefault(x=>x.GetType().GetProperty("MyProperty01") == "myCondition");

因为有时我需要搜索MyProperty01,有时需要搜索MyProperty02MyProperty03等。

编辑:在visual studio中我收到此错误:

"Operator '==' can't be applied to operands of type System.reflection.PropertyInfo and string".

3 个答案:

答案 0 :(得分:2)

是的,你能做到这一点。你非常接近,这是一个你可以放入linqpad的演示。请注意,重要的部分是

Single(l => l.GetType().GetProperty(prop).GetValue(l).ToString() == "Condition")

void Main()
{
 var myList = Enumerable.Range(0,10).Select(i => new Xmas(i,"name"+i)).ToList();
 string prop = "name";
 Console.WriteLine(myList.Single(l => l.GetType().GetProperty(prop).GetValue(l).ToString() == "name6").name);
}

public class Xmas
{
 public int id { get; set; }
 public string name { get; set; }
 public Xmas( int id, string name )
 {
  this.id = id;
  this.name = name;
 }
}

答案 1 :(得分:1)

工作示例:

public class Apple
{
    public string Color { get; set; }
}

public List<Apple> ApplesList {get;set;}

public void Process()
{
    PropertyInfo pi = typeof(Apple).GetProperty("Color");
    ApplesList = ApplesList.Where(r => (string)pi.GetValue(r) == "Red").ToList();
}

答案 2 :(得分:1)

您还可以编写一个Extension方法,它允许获取每个对象的属性,当它不存在时返回null,或者没有GetMethod。如果需要,可以保留缓存

public static class ObjectExtension
{
    static IDictionary<KeyValuePair<Type, string>, PropertyInfo> propertyCache = new Dictionary<KeyValuePair<Type, string>, PropertyInfo>();

    public static object GetProperty(this object source, string propertyName, bool useCache = true)
    {
        if (source == null)
        {
            return null;
        }
        var sourceType = source.GetType();
        KeyValuePair<Type, string> kvp = new KeyValuePair<Type, string>(sourceType, propertyName);
        PropertyInfo property = null;

        if (!useCache || !propertyCache.ContainsKey(kvp))
        {
            property = sourceType.GetProperty(propertyName);
            if (property == null)
            {
                return null;
            }
            var get = property.GetGetMethod();
            if (get == null)
            {
                return null;
            }
            if (useCache)
            {
                propertyCache.Add(kvp, property);
            }
        }
        else
        {
            property = propertyCache[kvp];
        }
        return property.GetValue(source, null);
    }

    public static T GetProperty<T>(this object source, string propertyName)
    {
        object value = GetProperty((object)source, propertyName);
        if (value == null)
        {
            return default(T);
        }
        return (T)value;
    }
}

一个小的测试类可以是:

public class Item
{
    public string MyProperty { get; set; }

    public string MyProperty3 { get; set; }

    public string MyProperty2 { protected get; set; }

    public Item()
    {
        MyProperty = "Test propery";
        MyProperty3 = "Test property 3";
        MyProperty2 = "Yoohoo";
    }
}

使用主要类进行测试

class Program
{
    static void Main(string[] args)
    {
        Item item = new Item();
        for (int x = 0; x < 4; x++)
        {
            string key = "MyProperty" + (x > 0 ? x.ToString() : "");
            string value = item.GetProperty<string>(key);
            Console.WriteLine("Getting {0} = {1}", key, value);
        }
        Console.ReadLine();
    }
}

给出了可预期的输出:

Getting MyProperty = Test propery
Getting MyProperty1 =
Getting MyProperty2 =
Getting MyProperty3 = Test property 3