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

如何在外部获取带约束泛型类的属性名称?

如何从带约束的泛型类中获取属性名称?

我定义了如下简单类:

class Simple 
{
    //...
}

还定义了一个带约束的泛型类:

class Generic<T> where T : Simple, new()
{
    public T SimpleObject { get; set; }

    public string Type { get; set; }
}

我想获取Generic<T>中Type属性的名称,尝试用Console.WriteLine(nameof(Generic.Type));时,编译器报错“使用泛型类型需要1个类型参数”。添加<>或者<object>也不行,因为object不满足T的约束。不想硬编码属性名(魔术字符串),避免后续重命名属性时出现不同步的bug,需要在Generic类外部(比如Program.cs)调用相关代码。


可行解决方案

1. 使用符合约束的具体类型参数

因为Simple本身满足Generic<T>的约束(是Simple的子类、有无参构造),直接用它作为类型参数即可:

Console.WriteLine(nameof(Generic<Simple>.Type));

这种方式最直接,编译器能正确识别,且属性重命名时nameof会自动同步更新。

2. 创建空派生类规避泛型参数

如果不想在代码中直接依赖Simple类型,可以创建一个继承自Generic<Simple>的空派生类:

class DummyGeneric : Generic<Simple> { }

之后就可以通过这个派生类获取属性名:

Console.WriteLine(nameof(DummyGeneric.Type));

后续只要Generic<T>的约束不变,这个空类无需修改就能正常使用。

3. 表达式树方式(适合复杂场景)

如果需要更灵活的方式,比如不知道具体的约束类型时,可以用表达式树提取属性名:

public static string GetPropertyName<T>(Expression<Func<T, object>> expression)
{
    if (expression.Body is MemberExpression memberExpr)
        return memberExpr.Member.Name;
    if (expression.Body is UnaryExpression unaryExpr && unaryExpr.Operand is MemberExpression operandMember)
        return operandMember.Member.Name;
    throw new ArgumentException("Invalid expression");
}

调用时传入符合约束的类型:

Console.WriteLine(GetPropertyName<Generic<Simple>>(x => x.Type));

这种方式代码量稍大,但扩展性更强。


为什么原写法不行?

nameof无法直接作用于未绑定的泛型类型(即未指定类型参数的Generic),必须提供一个满足泛型约束的有效类型参数,编译器才能解析对应的成员。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:49:56