Reputation: 13
I have a class composed of multiple lists and I have generic methods to allow me to do CRUD (and other) operations over those lists.
I'm basically trying to do a variation of DbContext.Set<T>
with List
.
This is my situation:
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
}
The problem is that my code gives me a list of the desired type, but no the actual list (i.e. the property). So any modifications to that list don't modify the property.
I'd like to be able to do something akin to A.List<T>
to get the list of that type (like DbContext
can do with DbContext.Set<T>
).
Upvotes: 1
Views: 45
Reputation: 271135
You have made a few mistakes here.
Bs
and Cs
are fields, not properties, so you should use GetFields
.
Bs
and Cs
are private, so you should use the binding flags NonPublic
and Instance
The result you get from Where
is an IEnumerable<T>
. You should call FirstOrDefault
or SingleOrDefault
to get a single field info.
After getting the field info, you need to call GetValue
to get the field's value.
p.GetType()
returns typeof(FieldInfo)
, not the declared type of the field. You should use FieldType
instead.
Here is the fixed version:
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);
}
}
Or, as thehennyy said in the comments, you should probably look into expression trees, specifically MemberExpression
s to do this. Reflection is quite slow.
Upvotes: 2