gpt4 book ai didi

c# - 使用 Roslyn 获取程序集属性

转载 作者:行者123 更新时间:2023-12-05 01:40:06 25 4
gpt4 key购买 nike

我希望能够使用 Roslyn 代码分析从程序集中的 AssemblyInfo.cs 文件中读取一些程序集属性。

所以给定以下示例:

using System;
using System.Collections.Generic;
using System.Text;

[assembly: Helloworld.TestAttribute1("Test1")]
[assembly: Helloworld.TestAttribute1(TheValue = "Test1", IgnoreThis = "I dont want this one!")]

namespace Helloworld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class TestAttribute1 : Attribute
{
public TestAttribute1()
{
}

public TestAttribute1(string theValue)
{
this.TheValue = theValue;
}

public string TheValue { get; set; }

public string IgnoreThis { get; set; }
}
}

我希望能够提取 TestAttribute1 类型的属性和名为 TheValue 的已定义属性的值。

这在示例中定义了两次 - 第一次使用构造函数参数,另一次使用命名参数。

我有以下代码:

static void Main(string[] args)
{
string cs = GetFile();

SyntaxTree tree = CSharpSyntaxTree.ParseText(cs);

var root = (CompilationUnitSyntax)tree.GetRoot();
var compilation = CSharpCompilation.Create("").AddSyntaxTrees(tree);
var model = compilation.GetSemanticModel(tree);

// get the attributes

AttributeSyntax attr1 = root.DescendantNodes()
.OfType<AttributeSyntax>().ToArray()[0];
AttributeSyntax attr2 = root.DescendantNodes()
.OfType<AttributeSyntax>().ToArray()[1];

var ex1 = attr1.ArgumentList.Arguments.FirstOrDefault().Expression as LiteralExpressionSyntax;
var str1 = ex1.GetText().ToString();

var ex2 = attr2.ArgumentList.Arguments.FirstOrDefault().Expression as LiteralExpressionSyntax;
var str2 = ex2.GetText().ToString();

}

目前我只是通过硬编码定位程序集属性来作弊。再次对 ArgumentList 进行硬编码以获取其中的第一个表达式。这让我得到 str1 和 str2 的结果是 \"Test1\"

有没有办法只说,给我 TestAttribute1 类型的属性,然后给我名为 TheValue 的属性的值?

最佳答案

您可以实现,只需尝试从 IAssemblySymbol 获取属性,此符号可以从 Compilation 中检索:

var attribute = compilation.Assembly.GetAttributes().FirstOrDefault(x => x.AttributeClass.ToString() == "Helloworld.TestAttribute1");
if(!(attribute is null))
{
var ctorArgs = attribute.ConstructorArguments;
var propArgs = attribute.NamedArguments;
}

ctorArgspropArgsTypedConstant 项和 TypedConstant 的集合(propArgs 是字典) 具有属性 Value(或 Values,当它是数组时)将传递的值保留为 ctor 参数或属性值。最后,您只需要使用 TypedConstant.Type 过滤您感兴趣的参数。

这应该如下所示:

SyntaxTree tree = CSharpSyntaxTree.ParseText(cs);

var root = (CompilationUnitSyntax)tree.GetRoot();
var compilation = CSharpCompilation.Create("test").AddSyntaxTrees(tree);

// get references to add
compilation = compilation.AddReferences(GetGlobalReferences());

var model = compilation.GetSemanticModel(tree);

var attrs = compilation.Assembly.GetAttributes().Where(x => x.AttributeClass.ToString() == "Helloworld.TestAttribute1");

foreach (var attr in attrs)
{
var ctorArgs = attr.ConstructorArguments;
var propArgs = attr.NamedArguments;
}
private static IEnumerable<MetadataReference> GetGlobalReferences()
{
var assemblies = new[]
{
typeof(System.Object).Assembly, //mscorlib
};

var refs = from a in assemblies
select MetadataReference.CreateFromFile(a.Location);

return refs.ToList();
}

关于c# - 使用 Roslyn 获取程序集属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57065238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com