C# 在 where 类型约束上使用反射的递归

问题描述 投票:0回答:2

我正在尝试通过类进行递归,但我不知道如何使用类型约束来调用它。

我的问题主要是我不知道如何调用递归并在分析调用上传递属性类型。

这是我的代码:

public class recursor 
{
    public string Analyze<T>() where T : class, new() 
    {
        StringBuilder sb = new StringBuilder();

        T t = new T();

        var propList = t.GetType().GetProperties();

        foreach (var prop in propList)
        {
            System.TypeCode propertyTypeCode = Type.GetTypeCode(prop.PropertyType);

            if (prop.PropertyType.IsClass)
            {
                // THIS IS WHAT I CAN'T FIGURE IT OUT
                // sb.Append(this.Analyze());
            }
            else
            {
                sb.Append("not a class");
            }
        }

        return sb.ToString();
    }
}

public class A {}

public class B {}

public class C {}
  
public class _container 
{
    public A _a;
    public B _b;
    public C _c;
}

public void main() 
{
   var r = new recursor();
   var s = r.Analyze<_container>();
}
c# recursion reflection where-clause type-constraints
2个回答
1
投票

这应该可以帮助您继续前进:

public class recursor
{
public string Analyze<T>() where T : class
{
    StringBuilder sb = new StringBuilder();

    var propList = typeof(T).GetProperties();

    foreach (var prop in propList)
    {
        System.TypeCode propertyTypeCode = Type.GetTypeCode(prop.PropertyType);
        if (prop.PropertyType.IsClass)
        {
            sb.Append(this.GetType().GetMethod("Analyze").MakeGenericMethod(prop.PropertyType).Invoke(this, null).ToString());
            sb.Append(prop.Name);
        }
        else
        {
            sb.Append("not a class");
        }
    }
    return sb.ToString();
}    

public class A { }
public class B { }
public class C { }

public class _container
{
    public A _a { get; set; }
    public B _b { get; set; }
    public C _c { get; set; }
}

这为我带来了

_a_b_c

递归并得到结果。您需要理解它以满足您的需求。


这是该方法的一个完全更好的版本:

public string Analyze2<T>() where T : class
    => this.Analyze2(typeof(T));

public string Analyze2(Type type)
    => String.Concat(
        type
            .GetProperties()
            .Select(p =>
                p.PropertyType.IsClass
                ? this.Analyze2(p.PropertyType)
                : "not a class"));

1
投票

您的通用方法还可以调用带有

Type
作为方法参数的方法。这个方法可以很容易地递归调用:

public string Analyze<T>() where T : class, new() 
    {
    return AnalyzeInternally(typeof(T));
    }

private string AnalyzeInternally(Type t)
{
    StringBuilder sb = new StringBuilder();
    var propList = t.GetProperties();
    foreach (var prop in propList)
    {
        System.TypeCode propertyTypeCode = Type.GetTypeCode(prop.PropertyType);

        if (prop.PropertyType.IsClass)
        {
            sb.Append(this.AnalyzeInternally(prop.PropertyType));
        }
        else
        {
            sb.Append("not a class");
        }
    }

    return sb.ToString();
}
© www.soinside.com 2019 - 2024. All rights reserved.