Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定字段是否可与Roslyn序列化_C#_Roslyn_Roslyn Code Analysis - Fatal编程技术网

C# 确定字段是否可与Roslyn序列化

C# 确定字段是否可与Roslyn序列化,c#,roslyn,roslyn-code-analysis,C#,Roslyn,Roslyn Code Analysis,我发现关于Roslyn的好文档很少,所以如果我遗漏了什么,请原谅,这应该是显而易见的。 我正在解析一些代码,我的目标是从类中提取每个可序列化字段 到目前为止,我得到的是这个。首先,我解析代码文件 SyntaxTree tree = CSharpSyntaxTree.ParseText(programText); CSharpCompilation compilation = CSharpCompilation.Create("HelloWorld"

我发现关于Roslyn的好文档很少,所以如果我遗漏了什么,请原谅,这应该是显而易见的。 我正在解析一些代码,我的目标是从类中提取每个可序列化字段

到目前为止,我得到的是这个。首先,我解析代码文件

            SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);
            CSharpCompilation compilation = CSharpCompilation.Create("HelloWorld")
                                                             .AddReferences(MetadataReference
                                                                                .CreateFromFile(typeof(object)
                                                                                                .Assembly
                                                                                                .Location))
                                                             .AddSyntaxTrees(tree);

            CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
接下来,我从每个类中获取所有字段

        foreach (MemberDeclarationSyntax member in root.Members)
        {
            if (member is ClassDeclarationSyntax classDeclarationSyntax)
            {

                foreach (MemberDeclarationSyntax rootGameMember in classDeclarationSyntax.Members)
                {
                    if (IsFieldSerializable(rootGameMember))
                    {
                    }
                }
            }
        }
AAAA现在我被卡住了。我想对这个字段做的是一些基于Unity 3D序列化规则的事情

  • 查看类型是否为public
  • 查看是否应用了属性[SerializeField]
  • 查看类型是否为int、float、string、double等
  • 查看类型是否具有[Serializable]属性

我想就是这样。目前,我正试图找出字段的类型,却迷失在一个选项的兔子圈中,似乎没有一个选项能满足我的需要。

您需要做的第一件事是获取表示字段的符号,这可以通过使用
SemanticModel
类来实现。我认为这将有助于解释如何根据示例获得语义模型:

TLDR:使用
compilation.GetSemanticModel()

这个问题回答了如何比我原来的答案做得更好,请看这里:

现在,您已经了解了该字段的语义信息,让我们一次一个地查看每个问题

1) 查看类型是否为public 这应该很简单,因为
IFieldSymbol
接口有一个
DeclaredAccessibility
属性,它将告诉您需要知道的内容

if(fieldSymbol.DeclaredAccessibility!=Accessibility.Public)
{
//对没有公众成员不感兴趣
}
2) 查看是否应用了属性
[SerializeField]
使用
IFieldSymbol
界面的
GetAttributes()
方法。然后,您可以像其他任何
INamedTypeSymbol
一样查询属性的
AttributeClass

var attributes=fieldSymbol.GetAttributes();
如果(!attributes.Any(attribute=>attribute.AttributeClass.Name==“序列化字段”))
{
//仅对具有SerializeField属性的字段感兴趣
}
3) 查看类型是否为
int
float
string
double
等 幸运的是,
Type
也是
IFieldSymbol
接口的一个属性,因此我们可以检查字段符号的该属性。如果只关心简单类型,则可以引用生成的
itypesymble
Name
属性

var fieldTypes=新列表{“int”、“float”、“string”、“double”};
如果(!fieldTypes.Contains(fieldSymbol.Type.Name))
{
//只对某些类型感兴趣
}
(您可能需要在调试器中仔细检查类型名称字符串)

4) 查看类型是否具有
[Serializable]
属性 从这里我猜您的意思是该类具有
[Serializable]
属性。为此,您可以使用与2相同的方法,但您需要类符号,因此这必须在字段检查函数之外完成

var classSymbol=model.GetSymbolInfo(classDeclarationSyntax).Symbol;
//记住要检查这个
var attributes=classSymbol.GetAttributes();
if(attributes.Any(attribute=>attribute.AttributeClass.Name==“可序列化”))
{
//类是可序列化的
}
编辑: 如果您认为按名称检查属性有点不方便,那么这个答案也可能对您有所帮助

IFieldSymbol:

INAMEDYPESYMBOL


我完全同意,顺便说一句,好的Roslyn文档似乎非常罕见。

非常感谢您提供的详细答案。这帮了大忙。现在我正在努力获取字段符号。这将是我猜测的两件事之一。类型为
public List
,因此SemanticModel不知道List或MyClass。我的代码库是从许多文件中解析出来的,因此我想我需要将它们全部包含在
CSharpSyntaxTree.ParseText
中,而不仅仅是第一个文件。如果问题是列表,那么我不确定如何解决。您需要列表符号中的
TypeArguments
。此外,语义模型中的
GetDeclaredSymbol
也值得使用。()