C#反思与反思;仿制药
有一个复杂的思考问题。给定下面的代码,您将如何实现pseudo,以便给定Parent的实例,它将枚举类型属性,找到具有与Parent相同类型属性的子对象,并将引用设置为提供的p。希望这是有道理的。我也需要这个来处理通用列表。请参见下面的示例对象图。运行此操作后,子宠物实例中的每个人都将成为父实例C#反思与反思;仿制药,c#,generics,reflection,C#,Generics,Reflection,有一个复杂的思考问题。给定下面的代码,您将如何实现pseudo,以便给定Parent的实例,它将枚举类型属性,找到具有与Parent相同类型属性的子对象,并将引用设置为提供的p。希望这是有道理的。我也需要这个来处理通用列表。请参见下面的示例对象图。运行此操作后,子宠物实例中的每个人都将成为父实例 public class ChildSetter<Parent> { public void Set(Parent p) {
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; }
}
我还没有测试过,但是:
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);
}
}
}
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
运用系统反思;
静态类程序
{
静态void Main()
{
...
}
公共静态void SetParent(T root)
{
foreach(PropertyInfo prop in typeof(T).GetProperties
(BindingFlags.Public | BindingFlags.Instance))
{
如果(!prop.CanRead)继续;
类型listType=null;
foreach(在prop.PropertyType.GetInterfaces()中键入interfaceType)
{
if(interfaceType.IsGenericType&&
interfaceType.GetGenericTypeDefinition()==typeof(IList))
{//IList检测到
listType=interfaceType.GetGenericArguments()[0];
}
}
List propsToSet=新列表();
foreach(PropertyInfo childProp in(listType??prop.PropertyType).GetProperties(
BindingFlags.Public | BindingFlags.Instance)
{
如果(childProp.PropertyType==typeof(T))propsToSet.Add(childProp);
}
如果(propsToSet.Count==0)继续;//无需执行任何操作
if(listType==null)
{
对象子对象=prop.GetValue(根,null);
如果(child==null)继续;
foreach(propsToSet中的PropertyInfo childProp)
{
SetValue(child,root,null);
}
}
其他的
{
IList list=(IList)prop.GetValue(root,null);
foreach(列表中的对象子对象)
{
如果(child==null)继续;
foreach(propsToSet中的PropertyInfo childProp)
{
SetValue(child,root,null);
}
}
}
}
}
}
我还没有测试过,但是:
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);
}
}
}
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
运用系统反思;
静态类程序
{
静态void Main()
{
...
}
公共静态void SetParent(T root)
{
foreach(PropertyInfo prop in typeof(T).GetProperties
(BindingFlags.Public | BindingFlags.Instance))
{
如果(!prop.CanRead)继续;
类型listType=null;
foreach(在prop.PropertyType.GetInterfaces()中键入interfaceType)
{
if(interfaceType.IsGenericType&&
interfaceType.GetGenericTypeDefinition()==typeof(IList))
{//IList检测到
listType=interfaceType.GetGenericArguments()[0];
}
}
List propsToSet=新列表();
foreach(PropertyInfo childProp in(listType??prop.PropertyType).GetProperties(
BindingFlags.Public | BindingFlags.Instance)
{
如果(childProp.PropertyType==typeof(T))propsToSet.Add(childProp);
}
如果(propsToSet.Count==0)继续;//无需执行任何操作
if(listType==null)
{
对象子对象=prop.GetValue(根,null);
如果(child==null)继续;
foreach(propsToSet中的PropertyInfo childProp)
{
SetValue(child,root,null);
}
}
其他的
{
IList list=(IList)prop.GetValue(root,null);
foreach(列表中的对象子对象)
{
如果(child==null)继续;
foreach(propsToSet中的PropertyInfo childProp)
{
SetValue(child,root,null);
}
}
}
}
}
}
此问题与此问题相关:此问题与此问题相关:谢谢Marc,我将检查它。获取列表后(在foreach之前)可能需要进行空检查,并且可能还需要检查childProp.CanWrite填充propsToSet时。我必须将此行从interfaceType.GetGenericTypeDefinition()更改为typeof(IList))到interfaceType.GetGenericTypeDefinition()==typeof(ICollection)),除此之外,由于堆,它100%工作。我会看看现在使用它是否合理:)谢谢Marc,我会检查它。在获取列表后(在foreach之前),可能需要进行空检查,并且可能还需要检查childProp.CanWrite来填充propsToSet。我必须将此行从interfaceType.GetGenericTypeDefinition()==typeof(IList))更改为interfaceType.GetGenericTypeDefinition()==typeof(ICollection))除此之外,它100%工作感谢堆。我会看看现在使用它是否明智:)