面试题答案
一键面试Source Generators适用场景
- 代码生成:在编译时生成重复或模板化的代码,减少手动编写重复代码的工作量。例如自动生成数据库访问层代码,根据数据库表结构生成对应的实体类和数据访问方法。
- 配置处理:根据配置文件或元数据生成特定代码。如根据XML配置文件生成依赖注入的注册代码。
- 优化性能:通过在编译期生成代码避免运行时反射等开销。例如生成高效的序列化/反序列化代码,避免运行时动态解析类型信息。
简单场景使用示例
- 创建项目:
- 创建一个.NET Standard类库项目,比如命名为
MySourceGenerator
。 - 创建一个新的类库项目,比如命名为
MyApp
,用于引用生成的代码。
- 创建一个.NET Standard类库项目,比如命名为
- 安装NuGet包:
- 在
MySourceGenerator
项目中,安装Microsoft.CodeAnalysis.CSharp.Scripting
和Microsoft.CodeAnalysis.Analyzers
包。
- 在
- 编写Source Generator:
- 在
MySourceGenerator
项目中创建一个源生成器类,例如:
- 在
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Collections.Generic;
using System.IO;
using System.Linq;
[Generator]
public class MySourceGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
// 初始化逻辑
}
public void Execute(GeneratorExecutionContext context)
{
// 获取语法树
var syntaxTrees = context.Compilation.SyntaxTrees;
var classDeclarations = new List<ClassDeclarationSyntax>();
foreach (var tree in syntaxTrees)
{
var root = tree.GetRoot();
classDeclarations.AddRange(root.DescendantNodes().OfType<ClassDeclarationSyntax>());
}
// 生成代码
var source = @"
namespace GeneratedCode
{
public static class GeneratedClass
{
public static string GetMessage()
{
return ""This is generated code"";
}
}
}";
context.AddSource("GeneratedCode.cs", SourceText.From(source, Encoding.UTF8));
}
}
- 使用生成的代码:
- 在
MyApp
项目中引用MySourceGenerator
项目。 - 编译
MyApp
项目后,即可在代码中使用生成的代码,例如:
- 在
using GeneratedCode;
using System;
namespace MyApp
{
class Program
{
static void Main()
{
var message = GeneratedClass.GetMessage();
Console.WriteLine(message);
}
}
}
这样在编译MyApp
项目时,MySourceGenerator
会生成GeneratedCode.cs
文件并添加到项目中,MyApp
项目就可以使用生成的GeneratedClass
类及其方法。