[英]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.