从类型确定类成员

时间:2013-12-04 12:11:14

标签: c# reflection

我有以下情况:

1)班级:

public class C
{
   public List<MyType> ListOfMyTypeObjects;
   public List<MyOtherType> ListOfMyOtherTypeObjects;
   public C()
   {
      this.ListOfMyTypeObjects = new List<MyType>;
      this.ListOfMyOtherTypeObjects = new List<MyOtherType>;
   }
}

2)界面:

public interface IInterface<T>
{
   object CreateObject(T source);
}

3)实施课程:

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)对象实例:

IDicionary<int, C> storage = new Dictionary{{1, new C()}};

如何识别与所需类型对应的成员,以及如何将对象添加到其中?

4 个答案:

答案 0 :(得分:1)

您可以使用反射(搜索通用列表字段):

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);
}

或者您可以使用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);
   }
}

答案 1 :(得分:1)

我实际上不会使用反射,因为你在类C中有固定数量的列表,你可以添加一个返回相应列表的方法:

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); 
   }
}

然后你可以这样做:

public object CreateObject(T source, int key)
{
    C c = (C)storage[key];
    var list = c.GetListFor<T>();
    list.Add(source);

    return source;
}

答案 2 :(得分:0)

你可以使用像这样的反射

   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<,>)) 

答案 3 :(得分:0)

我认为FieldInfo和PropertyInfo之间存在严重区别是有充分理由的,尽管他们的主题故意分享如此多的概念相似性。现在我无法想到任何好的。

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;
}