C#反射&泛型 [英] C# Reflection & Generics
本文介绍了C#反射&泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
public class ChildSetter< Parent>
{
public void Set(Parent p)
{
// pseudo
// var parentName = p.GetType()。Name;
// foreach(p.Properties中的var属性)
// {
// if(!property.IsList)
// {
// if( property.ContainsProperty(parentName))
// property.Properties [parentName] = p;
//}
// else
// {
// if(property.ListType.ContainsProperty(parentName))
// {
/ / foreach(属性中的var项)
// {
// item.Properties [parentName] = p;
//}
//}
//}
//}
}
}
public class Person
{
public Pet Pet {get;组; }
public IList< Pet>宠物{get;组; }
}
public class Pet
{
public Person Person {get;组; }
}
此代码的非泛型示例如下所示:
public void Set(Person p)
{
p.Pet.Person = p;
foreach(var pet in p.Pets)
{
pet.Person = p;
}
}
解决方案
I没有测试过,但怎么样:
using System;
使用System.Collections;
使用System.Collections.Generic;
使用System.Reflection;
静态类程序
{
static void Main()
{
...
}
public static void SetParent< (T).GetProperties
(BindingFlags.Public | BindingFlags.Instance))
{
(T)(T root)
{
foreach(PropertyInfo prop in typeof如果(!prop.CanRead)继续;
类型listType = null;
foreach(在prop.PropertyType.GetInterfaces()中输入interfaceType)
{
if(interfaceType.IsGenericType&&
interfaceType.GetGenericTypeDefinition()== typeof(IList< >))
{// IList< T>检测到
listType = interfaceType.GetGenericArguments()[0];
}
}
List< PropertyInfo> propsToSet =新列表< 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; //没什么可做的
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(列表中的对象子)
{
if(child == null)continue;
foreach(PropertyInfo childProp in propsToSet)
{
childProp.SetValue(child,root,null);
}
}
}
}
}
}
Got a complex reflection question. Given the code below how would you implement the pseudo so that given an instance of Parent it will enumerate over the types Properties find child objects with a Property of the same type as Parent and set the reference to the provided p. Hope that makes sense. Also I need this to work with Generic lists as well. See below for sample object graph. After running this every Person in the child Pet instances will be the Parent instance.
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; }
}
A non generic example of this code is below:
public void Set(Person p)
{
p.Pet.Person = p;
foreach (var pet in p.Pets)
{
pet.Person = p;
}
}
解决方案
I haven't tested it, but how about:
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);
}
}
}
}
}
}
这篇关于C#反射&泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文