我尝试MyAttribute用Roslyn 获取命名参数.
var sourceCode = (@"
public class MyAttribute : Attribute
{
public string Test { get; set; }
}
[MyAttribute(Test = ""Hello"")]
public class MyClass { }
");
var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create("MyCompilation", new[] { syntaxTree }, new[] { mscorlib });
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var syntaxRoot = syntaxTree.GetRoot();
var classNode = syntaxRoot.DescendantNodes().OfType<ClassDeclarationSyntax>().Skip(1).First();
var classModel = (ITypeSymbol)semanticModel.GetDeclaredSymbol(classNode);
var firstAttribute = classModel.GetAttributes().First();
Run Code Online (Sandbox Code Playgroud)
但是firstAttribute.AttributeClass.Kind等于ErrorType并且因此不firstAttribute.NamedArguments包含任何元素.
代码不是anlyzer或者我有更完整的上下文,比如解决方案.
我看不出roslyn缺少任何引用或其他内容.我该怎么做才能完全分析属性?
您需要完全限定Attribute类型名称:
var sourceCode = (@"
public class MyAttribute : System.Attribute // < here
{
public string Test { get; set; }
}
[MyAttribute(Test = ""Hello"")]
public class MyClass { }
");
Run Code Online (Sandbox Code Playgroud)
然后它将按预期工作:
var firstNamedArg = firstAttribute.NamedArguments[0];
var key = firstNamedArg.Key; // "Test"
var value = firstNamedArg.Value.Value; // "Hello"
Run Code Online (Sandbox Code Playgroud)
或者,您可以using System;在顶部添加:
var sourceCode = (@"
using System;
public class MyAttribute : Attribute
{
public string Test { get; set; }
}
[MyAttribute(Test = ""Hello"")]
public class MyClass { }
");
Run Code Online (Sandbox Code Playgroud)
SemanticModel您还可以简单地使用语法 API 来获取属性的参数信息,而不是使用 Roslyn :
var firstAttribute = classNode.AttributeLists.First().Attributes.First();
var attributeName = firstAttribute.Name.NormalizeWhitespace().ToFullString();
Console.WriteLine(attributeName);
// prints --> "MyAttribute"
var firstArgument = firstAttribute.ArgumentList.Arguments.First();
var argumentFullString = firstArgument.NormalizeWhitespace().ToFullString();
Console.WriteLine(argumentFullString);
// prints --> Test = "Hello"
var argumentName = firstArgument.NameEquals.Name.Identifier.ValueText;
Console.WriteLine(argumentName);
// prints --> Test
var argumentExpression = firstArgument.Expression.NormalizeWhitespace().ToFullString();
Console.WriteLine(argumentExpression);
// prints --> "Hello"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1216 次 |
| 最近记录: |