Silviu Preda
Silviu Preda

Reputation: 628

Determine class member from type

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

Answers (4)

George
George

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

Eren Ers&#246;nmez
Eren Ers&#246;nmez

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

sloth
sloth

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

BRAHIM Kamel
BRAHIM Kamel

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

Related Questions