获取嵌套属性及其父级的全名

时间:2018-04-18 06:39:45

标签: c# .net reflection

如何通过C#中的反射获取其父级的嵌套属性的全名?我的意思是,例如我们有这个类:

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public Grade Grade { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }
    public GradGroup GradGroup { get; set; }
}

public class GradGroup
{
    public int Id { get; set; }
    public string GroupName { get; set; }
}

我将“GradGroup”和Student作为方法参数,并希望“Grade.GradeGroup”作为输出:

public string GetFullPropertyName(Type baseType, string propertyName)
    {
        // how to implement that??
    }

调用方法:

GetFullPropertyName(typeof(Student), "GradeGroup"); // Output is Grade.GradeGroup

3 个答案:

答案 0 :(得分:7)

该属性可能不是唯一的,因为它可能存在于多个组件上,因此您应该返回IEnumerable<string>。话虽如此,您可以使用GetProperties的{​​{1}}遍历属性树:

Type

答案 1 :(得分:3)

  • 使用反射查找类型的所有属性
  • 使用面包优先搜索来查找具有给定名称的嵌套属性
  • 使用“。”
  • 连接在路径中找到的属性名称

以下是一些有用的参考资料

答案 2 :(得分:2)

好的,我太晚了,但这是我提出的解决方案:

public static class TypeExtensions
{
    public static IEnumerable<string> GetFullPropertyNames(this Type type, string propertyName)
    {
        if (type == null)
            throw new ArgumentNullException(nameof(type));

        if (String.IsNullOrWhiteSpace(propertyName))
            throw new ArgumentNullException(nameof(propertyName));

        return GetFullPropertyNamesImpl(type, propertyName, new HashSet<Type>());
    }

    private static IEnumerable<string> GetFullPropertyNamesImpl(Type type, string propertyName, ICollection<Type> visitedTypes)
    {
        if (visitedTypes.Contains(type))
            yield break;

        visitedTypes.Add(type);

        var matchingProperty = type.GetProperty(propertyName);

        if (matchingProperty != null)
        {
            yield return matchingProperty.Name;
        }

        foreach (var property in type.GetProperties())
        {
            var matches = GetFullPropertyNamesImpl(property.PropertyType, propertyName, visitedTypes);

            foreach (var match in matches)
            {
                yield return $"{property.Name}.{match}";
            }
        }
    }
}

使用此类示例:

public class GrandChild
{
    public int IntegerValue { get; set; }
    public string StringValue { get; set; }
    public bool BooleanValue { get; set; }
    public DateTime DateTimeValue { get; set; }
}

public class Child
{
    public GrandChild First { get; set; }
    public GrandChild Second { get; set; }
}

public class Parent
{
    public Child Mother { get; set; }
    public Child Father { get; set; }

}

你会称之为

public class Program
{
    public static void Main()
    {
        var matches = typeof(Parent).GetFullPropertyNames("Ticks");

        foreach (var match in matches)
        {
            Console.WriteLine(match);
        }

        Console.ReadKey();
    }
}

输出结果为:

  

Mother.First.DateTimeValue.Ticks

     

Mother.First.DateTimeValue.TimeOfDay.Ticks