繁体   English   中英

C#反射与泛型

[英]C# Reflection & Generics

有一个复杂的反思问题。 给定下面的代码,您将如何实现该伪函数,以便在给定Parent实例的情况下,将枚举类型Properties来查找具有与Parent类型相同的Property的子对象,并将引用设置为所提供的p。 希望有道理。 另外,我还需要使用它来处理通用列表。 请参阅下面的示例对象图。 运行此命令后,子Pet实例中的每个Person将成为Parent实例。

 public class ChildSetter<Parent>
    {
        public void Set(Parent p)
        {

            //pseudo 
            //var parentName = p.GetType().Name;
            //foreach (var property in p.Properties)
            //{
            //   if (!property.IsList)
            //   {
            //      if (property.ContainsProperty(parentName))
            //          property.Properties[parentName] = p;
            //   }
            //   else
            //   {
            //      if (property.ListType.ContainsProperty(parentName))
            //      {
            //          foreach (var item in property)
            //          {
            //              item.Properties[parentName] = p;
            //          }
            //      }
            //   }
            //}
        }
    }

public class Person
{
    public Pet Pet { get; set; }
    public IList<Pet> Pets { get; set; }

}

public class Pet
{
    public Person Person { get; set; }
}

该代码的一个非通用示例如下:

 public void Set(Person p)
    {
        p.Pet.Person = p;
        foreach (var pet in p.Pets)
        {
            pet.Person = p;
        }
    }

我还没有测试过,但是如何:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

static class Program
{
    static void Main()
    {
        ...
    }
    public static void SetParent<T>(T root)
    {
        foreach (PropertyInfo prop in typeof(T).GetProperties
            (BindingFlags.Public | BindingFlags.Instance))
        {
            if (!prop.CanRead) continue;

            Type listType = null;
            foreach (Type interfaceType in prop.PropertyType.GetInterfaces())
            {
                if (interfaceType.IsGenericType &&
                    interfaceType.GetGenericTypeDefinition() == typeof(IList<>))
                { // IList<T> detected
                    listType = interfaceType.GetGenericArguments()[0];
                }
            }

            List<PropertyInfo> propsToSet = new List<PropertyInfo>();
            foreach (PropertyInfo childProp in (listType ?? prop.PropertyType).GetProperties(
                BindingFlags.Public | BindingFlags.Instance))
            {
                if (childProp.PropertyType == typeof(T)) propsToSet.Add(childProp);
            }

            if(propsToSet.Count == 0) continue; // nothing to do
            if (listType == null)
            {
                object child = prop.GetValue(root, null);
                if (child == null) continue;
                foreach (PropertyInfo childProp in propsToSet)
                {
                    childProp.SetValue(child, root, null);
                }
            }
            else
            {
                IList list = (IList)prop.GetValue(root, null);
                foreach (object child in list)
                {
                    if (child == null) continue;
                    foreach (PropertyInfo childProp in propsToSet)
                    {
                        childProp.SetValue(child, root, null);
                    }
                }
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM