我有一个名为 Customer 的类,其中包含一些 setter 和 getter,其中包含一些字符串值。然后我创建一个列表并向其中添加许多 Customer 类。我如何使用反射访问 getter 和 setter 方法?
List<Customer> Customers; // assume we have filled it
Customers[0].Name; // how do I use reflection to call this from a string?
此外,Customer 类、Customers 和 Name 方法都是公共(public)的。
我处于这样一种情况,我需要根据用户尝试编辑的列从类中动态获取值。列名是我需要调用的方法的名称。
我查看了 GetType().GetMethod(),我的问题是如何将它与上面的列表一起使用。
一个例子可以解决我的问题。
最佳答案
更新:有一篇很好的文章解释了如何使用重构安全代码访问方法或属性并提供了代码。 http://www.codeducky.org/10-utilities-c-developers-should-know-part-two/
所有给出的答案都有效。但是,没有一个是重构安全的。我想我会提供一个更安全的重构解决方案。
//Create a dictionary of columnName => property info using the GetPropertyInfo method.
public static IDictionary<string, PropertyInfo> propertyInfos = new Dictionary<string, PropertyInfo>
{
{"Name", GetPropertyInfo((Customer c) => c.Name) }
};
List<Customer> Customers= new List<Customer> { new Customer { Name = "Peter Pan" } };
Customer customer = Customers[0];
string column = "Name";
PropertyInfo propertyInfo = propertyInfos[column];
//Set property
propertyInfo.SetValue(customer, "Captain Hook", null);
//Get property -- Returns Captain Hook
object propertyValue = propertyInfo.GetValue(customer, null);
我从 this answer 获取了 GetPropertyInfo
.我通过删除 source
参数对其进行了轻微修改,因为您可以从 HappyNomad 的 评论中看出,最新版本的 C# 不需要它。
public static PropertyInfo GetPropertyInfo<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertyLambda)
{
Type type = typeof(TSource);
MemberExpression member = propertyLambda.Body as MemberExpression;
if (member == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a method, not a property.",
propertyLambda.ToString()));
PropertyInfo propInfo = member.Member as PropertyInfo;
if (propInfo == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a field, not a property.",
propertyLambda.ToString()));
if (type != propInfo.ReflectedType &&
!type.IsSubclassOf(propInfo.ReflectedType))
throw new ArgumentException(string.Format(
"Expresion '{0}' refers to a property that is not from type {1}.",
propertyLambda.ToString(),
type));
return propInfo;
}
我的建议是更安全的重构,因为每次更改 Customer
的 Name
属性时都会遇到编译时错误。
旁注:我同意 Tim S. 的观点。您可能会找到比反射更安全、更高效的方法 :)。
关于c# - 反射调用列表中的类中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16865972/