给出任何复杂的对象,例如:
public class Person
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
我想使用 reflection 来获取string
实例的所有Person
和任何子对象(在这种情况下为Address
),并且从理论上讲Address
等中的潜在对象。在此示例中,这将为PropertyInfo
,Person.Name
和Address.Street
Address.City
答案 0 :(得分:3)
您可以扫描属性 graph (将其设为 Breadth First Search -BFS)以获得所有公共属性:
private static IEnumerable<PropertyInfo> PublicProps(Type value) {
HashSet<PropertyInfo> emitted = new HashSet<PropertyInfo>();
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
List<PropertyInfo> agenda = value
.GetProperties(flags)
.ToList();
while (agenda.Any()) {
for (int i = agenda.Count - 1; i >= 0; --i) {
PropertyInfo item = agenda[i];
agenda.RemoveAt(i);
if (!emitted.Add(item))
continue;
yield return item;
agenda.AddRange(item.PropertyType.GetProperties(flags));
}
}
}
然后使用 Linq 过滤掉string
属性:
var result = PublicProps(typeof(Person))
.Where(prop => prop.CanRead) // to be on the safe side if you want to read
.Where(prop => prop.PropertyType == typeof(string));
Console.WriteLine(string.Join(Environment.NewLine, result);
结果:
System.String Name
System.String City
System.String Street
请注意,递归不是一般情况下的解决方案,例如
public class Person {
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address {
public string Street { get; set; }
public string City { get; set; }
public Person HouseOwner { get; set; } // <- circular property
}
答案 1 :(得分:0)
using System;
using System.Reflection;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
getPRopNames(typeof(Person));
}
public static void getPRopNames(Type fromObject)
{
foreach (PropertyInfo oneProp in fromObject.GetProperties())
{
if (oneProp.PropertyType.IsValueType || oneProp.PropertyType == typeof(string))
{
Console.WriteLine(oneProp.Name);
}
else
{
getPRopNames(oneProp.PropertyType);
}
}
}
}
public class Person
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
}
答案 2 :(得分:0)
您可以使用反射来扫描属性。
public static void FindStringMembers(Type t, List<string>PropertyNames, int stackDepth = 0)
{
if (stackDepth >= 10) {
return;
}
var f = t.GetProperties();
var stringProperties = f.Where(x => x.PropertyType == typeof(string)).Select(x => x.Name);
PropertyNames.AddRange(stringProperties);
var otherProperties = f.Where(x => x.PropertyType != typeof(string));
foreach (var property in otherProperties) {
FindStringMembers(property.PropertyType, PropertyNames, stackDepth + 1);
}
}
static void Main(string[] args)
{
var bob = new Person();
var deepScan = new List<string>();
FindStringMembers(bob.GetType(), deepScan);
Console.WriteLine(string.Join("\n", deepScan));
}