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

泛型SQL命令生成代码中通过属性名获取属性值的疑问

嘿,我之前做泛型SQL生成器的时候也碰到过一模一样的嵌套属性取值问题!结合你给出的Question类结构,先补全一下合理的类定义方便举例(假设Answer是关联的内部类或独立类):

[Table("Question")]
public class Question 
{
    [Column("QuestionID", true)] 
    public int QuestionId { get; set; } 
    [Column("Number")] 
    public string Nr { get; set; } 
    // 假设这是你提到的Answer关联属性
    public Answer QuestionAnswer { get; set; }

    // 如果Answer是Question的内部类
    public class Answer
    {
        public string Content { get; set; }
        public int Score { get; set; }
    }
}

接下来给你两个实用的解决方案:

方案1:反射处理嵌套属性(简单易实现)

这种方式适合低频调用场景,直接通过反射拆分属性路径,逐层获取实例/值:

public static object GetNestedPropertyValue(object targetObj, string propertyPath)
{
    if (targetObj == null || string.IsNullOrWhiteSpace(propertyPath))
        return null;

    var propertySegments = propertyPath.Split('.');
    var currentInstance = targetObj;

    foreach (var propName in propertySegments)
    {
        if (currentInstance == null) break;

        var type = currentInstance.GetType();
        // 查找公开实例属性,如需支持非公开可调整BindingFlags
        var property = type.GetProperty(propName, BindingFlags.Public | BindingFlags.Instance);
        
        if (property == null)
            throw new ArgumentException($"找不到属性 {propName},所属类型:{type.FullName}");

        currentInstance = property.GetValue(currentInstance);
    }

    return currentInstance;
}

用法示例

// 获取Answer属性的实例
var answerInstance = GetNestedPropertyValue(myObject, "QuestionAnswer");
// 获取Answer实例中的Content值
var answerContent = GetNestedPropertyValue(myObject, "QuestionAnswer.Content");

方案2:表达式树(高性能高频调用首选)

反射每次调用都要重复查找属性,表达式树可以提前编译成委托,适合频繁调用的场景:

public static Func<T, object> CreateNestedPropertyGetter<T>(string propertyPath)
{
    var param = Expression.Parameter(typeof(T), "target");
    Expression expression = param;

    foreach (var propName in propertyPath.Split('.'))
    {
        expression = Expression.Property(expression, propName);
    }

    // 值类型需要装箱转换为object
    if (expression.Type.IsValueType)
    {
        expression = Expression.Convert(expression, typeof(object));
    }

    var lambda = Expression.Lambda<Func<T, object>>(expression, param);
    return lambda.Compile();
}

用法示例

// 提前编译一次,后续重复调用
var answerContentGetter = CreateNestedPropertyGetter<Question>("QuestionAnswer.Content");
// 快速取值
var contentValue = answerContentGetter(myObject);

额外注意点

  • 空值处理:如果中间某个属性是null,反射方案会返回null,你可以根据需求添加空值判断或抛出异常
  • 大小写敏感:默认反射是大小写敏感的,如果需要兼容不敏感的场景,可以自己实现属性名的模糊匹配逻辑
  • 内部类适配:不管Answer是独立类还是Question的内部类,上述两种方案都能正常工作,只要属性路径正确即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:59:35