我有一个由多个列表组成的类,并且有通用的方法可以让我对这些列表进行CRUD(及其他)操作。
我基本上是在尝试将DbContext.Set<T>
改成List
。
这是我的情况:
public class A
{
private IList<B> Bs;
private IList<C> Cs;
public A()
{
Administrators = new List<B>();
Developers = new List<C>();
}
public void Add<T>(T entity)
{
var propertyIWant = this.GetType().GetProperties().Where(p => p.GetType() == typeof(IList<T>));
var propertyAsList = propertyIWant as List<T>;
propertyAsList.Add(entity);
}
public void Delete<T>(T entity)
{
//Same idea
}
//Other methods
}
问题是我的代码为我提供了所需类型的列表,但没有 actual 列表(即属性)。 因此,对该列表的任何修改都不会修改该属性。
我希望能够进行类似于A.List<T>
的操作来获取该类型的列表(例如DbContext
可以与DbContext.Set<T>
一起使用)。
答案 0 :(得分:2)
您在这里犯了一些错误。
Bs
和Cs
是字段,而不是属性,因此您应使用GetFields
。
Bs
和Cs
是私有的,因此应使用绑定标志NonPublic
和Instance
从Where
获得的结果是IEnumerable<T>
。您应该致电FirstOrDefault
或SingleOrDefault
以获得单个字段信息。
获取字段信息后,您需要调用GetValue
来获取字段的值。
p.GetType()
返回typeof(FieldInfo)
,而不是字段的声明类型。您应该改用FieldType
。
这是固定版本:
public void Add<T>(T entity)
{
var fieldIWant = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(p => p.FieldType == typeof(IList<T>)).SingleOrDefault();
if (fieldIWant != null) {
var value = (IList<T>)fieldIWant.GetValue(this);
value.Add(entity);
}
}
或者,正如thehennyy在评论中所说,您可能应该查看表达式树,特别是MemberExpression
来做到这一点。反射速度很慢。