如何从上传的C#文件文本中提取所有类型并转为对象列表
从C#代码文本中提取类型并转换为对象列表的实现方案
要精准解析C#代码文本并提取类型信息,最靠谱的方式是用微软官方的Roslyn(.NET Compiler Platform),它能深度分析C#语法结构,避开正则表达式这类简易方案的各种边界问题。
第一步:引入依赖
先给项目安装对应的NuGet包:
Install-Package Microsoft.CodeAnalysis.CSharp
第二步:定义类型信息模型
先创建一个类来存储提取到的类型核心信息:
public class TypeInfo { public string Name { get; set; } public string TypeKind { get; set; } // 比如"Class"、"Interface"、"Struct" public string AccessModifier { get; set; } // 比如"public"、"internal" public List<string> MemberInfos { get; set; } = new List<string>(); }
第三步:编写代码解析核心逻辑
实现一个方法,将代码文本转换为语法树后,遍历提取所有类型节点:
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; public List<TypeInfo> ExtractTypesFromCode(string codeText) { var typeInfos = new List<TypeInfo>(); // 生成C#语法树 var syntaxTree = CSharpSyntaxTree.ParseText(codeText); var root = syntaxTree.GetRoot() as CompilationUnitSyntax; // 遍历所有类型声明节点 foreach (var typeNode in root.DescendantNodes().OfType<TypeDeclarationSyntax>()) { var info = new TypeInfo(); // 获取类型名称 info.Name = typeNode.Identifier.Text; // 判断类型种类 info.TypeKind = typeNode switch { ClassDeclarationSyntax => "Class", InterfaceDeclarationSyntax => "Interface", StructDeclarationSyntax => "Struct", _ => "Unknown" }; // 获取访问修饰符 var accessMod = typeNode.Modifiers.FirstOrDefault(m => m.IsKind(SyntaxKind.PublicKeyword) || m.IsKind(SyntaxKind.InternalKeyword)); info.AccessModifier = accessMod?.Text ?? "internal"; // 提取成员信息(简化处理,可按需扩展) foreach (var member in typeNode.Members) { if (member is PropertyDeclarationSyntax prop) { info.MemberInfos.Add($"属性: {prop.Type} {prop.Identifier.Text}"); } else if (member is MethodDeclarationSyntax method) { info.MemberInfos.Add($"方法: {method.ReturnType} {method.Identifier.Text}"); } } typeInfos.Add(info); } return typeInfos; }
第四步:整合到文件读取方法里
修改你现有的GetClassType方法,调用上面的解析逻辑:
public async Task<List<TypeInfo>> GetClassType(IFormFile file) { using var reader = new StreamReader(file.OpenReadStream()); var codeText = await reader.ReadToEndAsync(); return ExtractTypesFromCode(codeText); }
额外说明
如果需要更深入的分析(比如类型继承关系、泛型参数、特性标记),可以基于Roslyn的语义分析(构建Compilation对象)实现,比单纯的语法树分析更精准;若要处理命名空间、using指令,可额外解析NamespaceDeclarationSyntax节点。
内容的提问来源于stack exchange,提问作者Amir Kian
相关产品推荐
相关产品推荐

