Reputation: 628
I have the following scenario:
1) Class:
public class C
{
public List<MyType> ListOfMyTypeObjects;
public List<MyOtherType> ListOfMyOtherTypeObjects;
public C()
{
this.ListOfMyTypeObjects = new List<MyType>;
this.ListOfMyOtherTypeObjects = new List<MyOtherType>;
}
}
2) Interface:
public interface IInterface<T>
{
object CreateObject(T source);
}
3) Implementing class:
public class Implementing<T> : IInterface<T> where T: SomeGeneralType
{
public object CreateObject(T source, int key)
{
//i know T can be of type MyType, but it can also be MyOtherType
C c = (C)storage[key];
//here, i would like to add to one of my members the source object,
//but without specifically know it is called that; in other words, i would like
//to scan c and find if it has any List<T> members; in that case, add to the
//found member (which is unique) the source object and return something,
//doesn't matter what
}
}
4)Object instance:
IDicionary<int, C> storage = new Dictionary{{1, new C()}};
How can I identify the member which corresponds to the desired type, and how can I add the object to it?
Upvotes: 0
Views: 84
Reputation: 2801
I believe there was a good reason for the severe distinction between FieldInfo and PropertyInfo, despite their subjects intentionally sharing so many conceptual similarities. Presently I can't think of any good one.
static IEnumerable<MemberInfo> GetMembers(Type type)
{
var properties = type.GetProperties();
var fields = type.GetFields();
return properties.Cast<MemberInfo>().Concat(fields);
}
static Type GetMemberType(MemberInfo m)
{
return m is PropertyInfo
? (m as PropertyInfo).PropertyType
: (m as FieldInfo).FieldType;
}
Upvotes: 0
Reputation: 39085
I actually wouldn't use reflection for this since you have a fixed number of lists within class C
, you can add a method that returns the appropriate list:
public class C
{
public List<MyType> ListOfMyTypeObjects;
public List<MyOtherType> ListOfMyOtherTypeObjects;
public C()
{
this.ListOfMyTypeObjects = new List<MyType>;
this.ListOfMyOtherTypeObjects = new List<MyOtherType>;
}
public List<T> GetListFor<T>()
{
if(typeof(T) == typeof(MyType))
return ListOfMyTypeObjects as List<T>;
else if(typeof(T) == typeof(MyOtherType))
return ListOfMyOtherTypeObjects as List<T>;
else
throw new TypeArgumentException("No list properties defined for " +
typeof(T).Name);
}
}
Then you can do this:
public object CreateObject(T source, int key)
{
C c = (C)storage[key];
var list = c.GetListFor<T>();
list.Add(source);
return source;
}
Upvotes: 1
Reputation: 101032
You can use reflection (searching for a generic list field):
void Main()
{
var c = new C();
Set(new MyType(), c);
Set(new MyOtherType(), c);
}
void Set<T>(T item, C c)
{
var field = typeof(C).GetFields().SingleOrDefault(x => x.FieldType.GetInterface(typeof(IList).FullName) != null &&
x.FieldType.GetGenericArguments().All(ft => ft == typeof(T)));
((IList)field.GetValue(c)).Add(item);
}
or you can use dynamic
:
void Main()
{
var c = new C();
SetDynamic(new MyType(), c);
SetDynamic(new MyOtherType(), c);
}
void SetDynamic<T>(T item, C c)
{
((dynamic)c).Add(item);
}
public class C
{
///...
public void Add(MyType item)
{
ListOfMyTypeObjects.Add(item);
}
public void Add(MyOtherType item)
{
ListOfMyOtherTypeObjects.Add(item);
}
}
Upvotes: 1
Reputation: 13755
you can use reflection something like this
using System.Reflection;
PropertyInfo[] properties = Item.GetType().GetProperties();
you can iterate through propeerties
foreach (PropertyInfo p in properties)
{
if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
Upvotes: 0