You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#带类型约束的反射递归调用实现问题求助

解决带类型约束的泛型方法递归调用问题

你的核心问题是泛型方法Analyze<T>需要编译时确定泛型参数,但属性类型是运行时通过反射获取的,无法直接作为泛型参数传入。要实现递归,得用反射动态构造并调用泛型版本的Analyze方法,同时要确保属性类型满足class, new()的约束条件。

修改后的完整代码如下:

using System.Text;
using System.Reflection;

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)
        {
            // 过滤:仅处理满足class+new()约束的自定义类,排除string等特殊引用类型
            if (prop.PropertyType.IsClass && 
                prop.PropertyType.GetConstructor(Type.EmptyTypes) != null && 
                prop.PropertyType != typeof(string))
            {
                // 通过反射获取泛型方法定义并构造具体泛型方法
                var analyzeMethod = typeof(recursor).GetMethod(nameof(Analyze), BindingFlags.Public | BindingFlags.Instance);
                var genericAnalyze = analyzeMethod.MakeGenericMethod(prop.PropertyType);
                // 调用递归方法并拼接结果
                string recursiveResult = (string)genericAnalyze.Invoke(this, null);
                sb.AppendLine($"递归分析类 {prop.PropertyType.Name}: {recursiveResult}");
            }
            else
            {
                sb.AppendLine($"属性 {prop.Name} 类型 {prop.PropertyType.Name}: 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; }
    public string Text { get; set; } // 测试特殊引用类型string
}

public class Program
{
    public static void Main() 
    {
       var r = new recursor();
       var s = r.Analyze<_container>();
       Console.WriteLine(s);
    }
}

关键说明:

  1. 反射调用泛型方法:

    • 先通过typeof(recursor).GetMethod获取Analyze方法的泛型定义
    • 用MakeGenericMethod(prop.PropertyType)构造对应属性类型的具体泛型方法
    • 最后用Invoke调用方法,传入当前实例this作为调用对象
  2. 约束校验:

    • 增加prop.PropertyType.GetConstructor(Type.EmptyTypes) != null判断,确保属性类型有公共无参构造函数,符合new()约束
    • 排除string类型:它虽然是引用类型,但无参构造函数不是公共的,无法满足new()约束,直接调用会报错
  3. 属性定义修正:原代码中_container的字段没有定义为属性(缺少get/set),GetProperties()无法获取到,所以修改为自动属性{ get; set; }

运行后,会递归分析_container的_a、_b、_c属性对应的类,同时正确识别Text属性为特殊引用类型,输出对应结果。

内容的提问来源于stack exchange,提问作者Merak Marey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:17:33