C# 是否可以动态设置条件的属性?
通常,当我想查找列表的第一个或默认项时,我会使用以下方式:C# 是否可以动态设置条件的属性?,c#,C#,通常,当我想查找列表的第一个或默认项时,我会使用以下方式: myList.SingleOrDefault(x=>x.MyPropery01 == "myCondition"); 但是,我想知道,如果我动态地设置属性MyProperty,例如,通过反射,是否可能: myList.SingleOrDefault(x=>x.GetType().GetProperty("MyProperty01") == "myCondition"); 因为有时候我需要搜索MyProperty01,有时
myList.SingleOrDefault(x=>x.MyPropery01 == "myCondition");
但是,我想知道,如果我动态地设置属性MyProperty
,例如,通过反射,是否可能:
myList.SingleOrDefault(x=>x.GetType().GetProperty("MyProperty01") == "myCondition");
因为有时候我需要搜索MyProperty01
,有时候我需要搜索MyProperty02
,MyProperty03
,等等
编辑:在visual studio中,我遇到以下错误:
"Operator '==' can't be applied to operands of type System.reflection.PropertyInfo and string".
工作示例:
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();
}
公共类苹果
{
公共字符串颜色{get;set;}
}
公共列表ApplesList{get;set;}
公共程序()
{
PropertyInfo pi=typeof(Apple).GetProperty(“颜色”);
ApplesList=ApplesList.Where(r=>(string)pi.GetValue(r)=“Red”).ToList();
}
工作示例:
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();
}
公共类苹果
{
公共字符串颜色{get;set;}
}
公共列表ApplesList{get;set;}
公共程序()
{
PropertyInfo pi=typeof(Apple).GetProperty(“颜色”);
ApplesList=ApplesList.Where(r=>(string)pi.GetValue(r)=“Red”).ToList();
}
是的,你可以做到。你很接近,这是一个你可以在linqpad上看到的演示。请注意,重要的部分是
Single(l=>l.GetType().GetProperty(prop).GetValue(l).ToString()=“条件”)
是的,你能做到。你很接近,这是一个你可以在linqpad上看到的演示。请注意,重要的部分是
Single(l=>l.GetType().GetProperty(prop).GetValue(l).ToString()=“条件”)
您还可以编写一个扩展方法,允许获取每个对象的属性,当它不存在或没有GetMethod时返回null。如果你想的话,你可以保留一个缓存
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;
}
}
使用主类进行测试
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();
}
}
您还可以编写一个扩展方法,允许获取每个对象的属性,当它不存在或没有GetMethod时返回null。如果你想的话,你可以保留一个缓存
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;
}
}
使用主类进行测试
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();
}
}
是的,这是有效的。你有没有试过并遇到问题?你能传递一个表达式吗?不管怎么说,代码似乎是有效的,也许你想要的是一个字典,而不是一个带有属性的类型?是的,或者一个索引器(谁可以为你做反射部分;)@lvaroGarcía-这是因为你必须从属性信息中获取值,请看下面的答案,以获取示例。是的,这是有效的。你有没有试过并遇到问题?你能传递一个表达式吗?不管怎么说,代码似乎是有效的,可能可以工作。也许你想要的是一个字典,而不是一个带有属性的类型?是的,或者一个索引器(可以为你做反射部分;)@lvaroGarcía-这是因为你必须从属性信息中获取值,请看下面的答案作为示例。还没有人告诉您必须使用propertyInfo方法SetValue来设置它。@约翰:这与问题有什么关系?@JohnPeters-为什么有人在这里使用SetValue?这是关于在枚举时获取值。列表的值已经在第一行实例化了。我假设标题表明他们想要设置一个值。(没有仔细阅读内容)还没有人告诉你必须使用propertyInfo方法SetValue来设置它。@约翰:这与问题有什么关系?@JohnPeters-为什么有人会在这里使用SetValue?这是关于在枚举时获取值。列表的值已经在第一行实例化了。我假设标题表明他们想要设置一个值。(没有仔细阅读)