简体   繁体   English

使用 Microsoft.CodeAnalysis,如何获取 Type 类型的 Attribute 属性的值?

[英]Using Microsoft.CodeAnalysis, how do I get the value of an Attribute property that is of type Type?

I have an Attribute class used to decorate an assembly for use in C# source code generators.我有一个Attribute类,用于装饰用于 C# 源代码生成器的程序集。 I am trying to get the value of one of the arguments that is type System.Type.我正在尝试获取 System.Type 类型的参数之一的值。 I can get the values of the other properties just fine.我可以很好地获取其他属性的值。

Here's the attribute class:这是属性类:

    [AttributeUsage(AttributeTargets.Assembly)]
    public class MigrationFunctionAttribute : Attribute
    {
        public Type MigrationFunction { get; set; }

        public string MigrationMethod { get; set; }
        public string DependsOn { get; set; }
        public string SqlScriptBucket { get; set; }
        // ATTRIBUTE:  ADD HERE
        public string Branch { get; set; }

    }

Here's my usage of the attribute:这是我对该属性的用法:

[assembly: MigrationFunction(MigrationFunction = typeof(MigrationFunctions), MigrationMethod = nameof(MigrationFunctions.MyMigrator), Branch = "@Branch", DependsOn = "Restore")]

After receiving the attribute in the SyntaxReceiver , I try to build a model from the information:SyntaxReceiver中接收到属性后,我尝试根据信息构建模型:

    public static AttributeModel2<IMigrationFunctionAttributeModel> Build(AttributeSyntax receiverMigrationFunctionAttribute, GeneratorExecutionContext context)
    {

        SemanticModel semanticModel = context.Compilation.GetSemanticModel(receiverMigrationFunctionAttribute.SyntaxTree);

        foreach (var attributeArgumentSyntax in receiverMigrationFunctionAttribute.ArgumentList.Arguments)
        {
            switch (attributeArgumentSyntax.NameEquals.Name.Identifier.ValueText)
            {
                case nameof(MigrationFunctionAttribute.MigrationFunction):


                    Debug.WriteLine(attributeArgumentSyntax.Expression);
                    // ^^^ outputs 'typeof(MigrationFunctions)'

                    TypeInfo t = semanticModel.GetTypeInfo(attributeArgumentSyntax.Expression);
                    Debug.WriteLine(t.Type.ToDisplayString());
                    // ^^^ outputs 'System.Type'


                    /// HOW DO I GET THE TYPE HERE, which should be "MigrationFunctions", not "System.Type"???
                    break;
                case nameof(MigrationFunctionAttribute.Branch):

                    var value = semanticModel.GetConstantValue(attributeArgumentSyntax.Expression);
                    Debug.WriteLine(value.Value);
                    // ^^^ outputs '@Branch just fine
                    break;

            }
        }
        
        return null;

    }

The model builder method can pick through the arguments as expected, but I cannot figure out how to get the correct type info for the property:模型构建器方法可以按预期选择参数,但我无法弄清楚如何获取属性的正确类型信息:

public Type MigrationFunction { get; set; }

I get System.Type , whereas I am expecting to get MigrationFunctions .我得到System.Type ,而我期望得到MigrationFunctions

When I output from, I get typeof(MigrationFunctions) :当我输出时,我得到typeof(MigrationFunctions)

Debug.WriteLine(attributeArgumentSyntax.Expression);

As documented in the code, HOW DO I GET THE TYPE HERE, which should be "MigrationFunctions", not "System.Type"???如代码中所述,我如何在此处获取类型,应该是“MigrationFunctions”,而不是“System.Type”???

You're definitely on the right track.你肯定在正确的轨道上。 Let's home in on this part:让我们回到这部分:

TypeInfo t = semanticModel.GetTypeInfo(attributeArgumentSyntax.Expression);
Debug.WriteLine(t.Type.ToDisplayString());
// ^^^ outputs 'System.Type'

As you note, GetTypeInfo when invoked with attributeArgumentSyntax.Expression returns a TypeInfo representing System.Type .正如您所注意到的,当使用attributeArgumentSyntax.Expression调用GetTypeInfo时,会返回一个表示System.TypeTypeInfo This makes sense because the declared type of that attribute property is System.Type .这是有道理的,因为该属性属性的声明类型是System.Type

You can still get the type you're after ( MigrationFunctions ) but you have to dig a little deeper.你仍然可以获得你想要的类型( MigrationFunctions ),但你必须更深入地挖掘。 First cast the expression to TypeOfExpressionSyntax :首先将表达式转换为TypeOfExpressionSyntax

var typeOfExpression = (TypeOfExpressionSyntax)attributeArgumentSyntax.Expression;

With that you can get the actual TypeSyntax representing typeof(MigrationFunctions) :有了它,您可以获得表示typeof(MigrationFunctions)的实际TypeSyntax

var typeSyntax = typeOfExpression.Type;

Finally, you can get the ITypeSymbol for MigrationFunctions :最后,您可以获得MigrationFunctionsITypeSymbol

var type = semanticModel.GetTypeInfo(typeSyntax);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 memory 中编译并使用 Microsoft.CodeAnalysis 获取程序集 - How to compile in memory and get assembly using Microsoft.CodeAnalysis 如何使用 Microsoft.CodeAnalysis(或类似)获取项目(.csproj)的目标框架? - How to get the Target Framework/s of a project (.csproj) using Microsoft.CodeAnalysis (or similar)? 尽管能够导航到定义,但名称空间“Microsoft.CodeAnalysis”中不存在类型或命名空间“MSBuild” - Type or namespace 'MSBuild' does not exist in namespace 'Microsoft.CodeAnalysis' despite being able to navigate to definition 使用Roslyn(Microsoft.CodeAnalysis)查询WebSite项目的信息 - Using Roslyn (Microsoft.CodeAnalysis) to query information of WebSite projects 无法加载文件或程序集 Microsoft.CodeAnalysis - Could not load file or assembly Microsoft.CodeAnalysis 在Roslyn与Microsoft.CodeAnalysis中添加MetadataReference - Adding MetadataReference in Roslyn Vs Microsoft.CodeAnalysis Microsoft.CodeAnalysis无法加载文件 - Microsoft.CodeAnalysis failed to load file 在哪里阅读Microsoft.CodeAnalysis的文档? - Where to read docs for Microsoft.CodeAnalysis? 如何将Microsoft.CodeAnalysis.ITypeSymbol与System.Type进行比较 - How to compare a Microsoft.CodeAnalysis.ITypeSymbol to a System.Type 如何在Roslyn(Microsoft.CodeAnalysis)中向生成的方法添加参数? -需要确切的语法 - How to add parameters to generated method in Roslyn ( Microsoft.CodeAnalysis )? - Need exact syntax
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM