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

如何使用C# Source Generator获取类成员的编译期默认值

C# 9 Source Generator 获取属性默认值方案

你需要结合Roslyn的语法解析能力+语义模型来提取属性的初始化默认值,这类默认值属于语法树中的赋值子节点,具体实现步骤如下:

  • 第一步:在Generator中通过语法接收器筛选所有带初始化逻辑的属性声明节点,或者直接遍历语法树定位到目标PropertyDeclarationSyntax节点
  • 第二步:检查属性节点是否包含EqualsValueClause,也就是= 1对应的语法节点,不存在则说明该属性没有设置默认值
  • 第三步:通过SemanticModel的GetConstantValue方法计算该赋值表达式的编译期常量值,就能拿到你需要的默认值

完整实现示例如下:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

[Generator]
public class DefaultValueExtractGenerator : ISourceGenerator
{
    public void Initialize(GeneratorInitializationContext context)
    {
        // 注册语法接收器,预筛选符合条件的属性节点
        context.RegisterForSyntaxNotifications(() => new PropertySyntaxReceiver());
    }

    public void Execute(GeneratorExecutionContext context)
    {
        if (context.SyntaxReceiver is not PropertySyntaxReceiver receiver) return;
        
        foreach (var property in receiver.TargetProperties)
        {
            var semanticModel = context.Compilation.GetSemanticModel(property.SyntaxTree);
            // 读取属性的默认值赋值节点
            if (property.Initializer is EqualsValueClauseSyntax valueClause)
            {
                // 计算编译期常量值
                var constantResult = semanticModel.GetConstantValue(valueClause.Value);
                if (constantResult.HasValue)
                {
                    // 此处拿到的就是你需要的默认值,示例场景下取值为1
                    object defaultValue = constantResult.Value;
                    // 后续自行处理拿到的默认值即可
                }
            }
        }
    }

    // 自定义语法接收器,提前收集所有带初始化逻辑的属性
    private class PropertySyntaxReceiver : ISyntaxReceiver
    {
        public List<PropertyDeclarationSyntax> TargetProperties { get; } = new();
        
        public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
        {
            if (syntaxNode is PropertyDeclarationSyntax { Initializer: not null } property)
            {
                TargetProperties.Add(property);
            }
        }
    }
}

注意:该方法只能获取编译期可确定的常量默认值,如果默认值是运行时计算的表达式(比如= DateTime.Now、= new CustomClass()),GetConstantValue会返回无值状态,这类场景需要你自行解析表达式节点生成对应的实现逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 11:06:04