SyntaxFactory 高级用法 - Part 1
本文档介绍 SyntaxFactory 的高级用法和技巧(第一部分)。
📋 文档信息
- 难度级别: 高级
- 预计阅读时间: 20 分钟
SyntaxFactory 楂樼骇
馃搵 鏂囨。淇℃伅
闅惧害: 馃敶 楂樼骇
棰勮闃呰鏃堕棿: 35 鍒嗛挓
鍓嶇疆鐭ヨ瘑:
- SyntaxFactory 鍩虹
- C# 娉涘瀷鍜岀壒鎬?
- 璁捐妯″紡鍩虹
閫傚悎浜虹兢:
- 闇€瑕佺敓鎴愬鏉備唬鐮佺粨鏋勭殑寮€鍙戣€?
- 楂樼骇婧愮敓鎴愬櫒寮€鍙戣€?
- 浠g爜鐢熸垚宸ュ叿鏋舵瀯甯?
馃搵 蹇€熷鑸?
| 绔犺妭 | 闅惧害 | 闃呰鏃堕棿 | 閾炬帴 |
|---|---|---|---|
| 澶嶆潅缁撴瀯鐢熸垚 | 馃敶 | 10 鍒嗛挓 | 鏌ョ湅 |
| 娉涘瀷绫荤敓鎴? | 馃敶 | 5 鍒嗛挓 | [鏌ョ湅](#鐢熸垚娉涘瀷绫? |
| 鐗规€х敓鎴? | 馃煛 | 5 鍒嗛挓 | 鏌ョ湅 |
| 鎺ュ彛鍜屾灇涓? | 馃煛 | 5 鍒嗛挓 | 鏌ョ湅 |
| 鐪熷疄浣跨敤鍦烘櫙 | 馃敶 | 10 鍒嗛挓 | 鏌ョ湅 |
馃幆 姒傝
鏈枃妗d粙缁?SyntaxFactory 鐨勯珮绾т娇鐢ㄦ妧鏈紝鍖呮嫭澶嶆潅缁撴瀯鐨勭敓鎴愩€佹硾鍨嬬被銆佺壒鎬с€佹帴鍙g瓑銆?
**鏈枃妗f兜鐩?*:
- 澶嶆潅绫荤粨鏋勭殑鐢熸垚
- 娉涘瀷绫诲拰鏂规硶鐨勭敓鎴?
- 鐗规€э紙Attributes锛夌殑鐢熸垚
- 鎺ュ彛鍜屾灇涓剧殑鐢熸垚
- 鐪熷疄椤圭洰涓殑浣跨敤鍦烘櫙
鍏稿瀷搴旂敤鍦烘櫙:
- DTO 绫昏嚜鍔ㄧ敓鎴?
- Builder 妯″紡浠g爜鐢熸垚
- API 瀹㈡埛绔唬鐮佺敓鎴?
- 澶嶆潅鐨勪唬鐮侀噸鏋勫伐鍏?
澶嶆潅缁撴瀯鐢熸垚
鐢熸垚绫?
csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勭被
/// </summary>
public class ClassGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曠殑 POCO 绫?
/// </summary>
public ClassDeclarationSyntax GeneratePocoClass(
string className,
Dictionary<string, string> properties)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword));
// 娣诲姞灞炴€?
foreach (var prop in properties)
{
var property = PropertyDeclaration(
ParseTypeName(prop.Value),
Identifier(prop.Key))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
classDecl = classDecl.AddMembers(property);
}
return classDecl;
}
/// <summary>
/// 鐢熸垚甯︽瀯閫犲嚱鏁扮殑绫?
/// </summary>
public ClassDeclarationSyntax GenerateClassWithConstructor(
string className,
Dictionary<string, string> parameters)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword));
// 娣诲姞瀛楁
foreach (var param in parameters)
{
var field = FieldDeclaration(
VariableDeclaration(ParseTypeName(param.Value))
.AddVariables(
VariableDeclarator(Identifier($"_{param.Key}"))))
.AddModifiers(
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.ReadOnlyKeyword));
classDecl = classDecl.AddMembers(field);
}
// 鍒涘缓鏋勯€犲嚱鏁?
var constructor = ConstructorDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddParameterListParameters(
parameters.Select(p =>
Parameter(Identifier(p.Key))
.WithType(ParseTypeName(p.Value)))
.ToArray())
.WithBody(Block(
parameters.Select(p =>
ExpressionStatement(
AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
IdentifierName($"_{p.Key}"),
IdentifierName(p.Key))))
.ToArray()));
classDecl = classDecl.AddMembers(constructor);
return classDecl;
}
/// <summary>
/// 鐢熸垚瀹炵幇鎺ュ彛鐨勭被
/// </summary>
public ClassDeclarationSyntax GenerateClassWithInterface(
string className,
string interfaceName)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddBaseListTypes(
SimpleBaseType(IdentifierName(interfaceName)));
return classDecl;
}
}鐢熸垚娉涘瀷绫?
csharp
/// <summary>
/// 鐢熸垚娉涘瀷绫荤殑绀轰緥
/// </summary>
public class GenericClassGeneration
{
/// <summary>
/// 鐢熸垚娉涘瀷绫伙細public class Container<T> { }
/// </summary>
public ClassDeclarationSyntax GenerateGenericClass()
{
return ClassDeclaration("Container")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(
TypeParameter("T"));
}
/// <summary>
/// 鐢熸垚甯︾害鏉熺殑娉涘瀷绫?
/// public class Repository<T> where T : class, new() { }
/// </summary>
public ClassDeclarationSyntax GenerateGenericClassWithConstraints()
{
return ClassDeclaration("Repository")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(
TypeParameter("T"))
.AddConstraintClauses(
TypeParameterConstraintClause("T")
.AddConstraints(
ClassOrStructConstraint(SyntaxKind.ClassConstraint),
ConstructorConstraint()));
}
/// <summary>
/// 鐢熸垚澶氫釜绫诲瀷鍙傛暟鐨勬硾鍨嬬被
/// public class Pair<TKey, TValue> { }
/// </summary>
public ClassDeclarationSyntax GenerateMultipleTypeParametersClass()
{
return ClassDeclaration("Pair")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(
TypeParameter("TKey"),
TypeParameter("TValue"));
}
}鐢熸垚鐗规€э紙Attributes锛?
csharp
/// <summary>
/// 鐢熸垚鐗规€х殑绀轰緥
/// </summary>
public class AttributeGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曠壒鎬э細[Serializable]
/// </summary>
public AttributeListSyntax GenerateSimpleAttribute()
{
return AttributeList(
SingletonSeparatedList(
Attribute(IdentifierName("Serializable"))));
}
/// <summary>
/// 鐢熸垚甯﹀弬鏁扮殑鐗规€э細[Table("Users")]
/// </summary>
public AttributeListSyntax GenerateAttributeWithArgument()
{
return AttributeList(
SingletonSeparatedList(
Attribute(IdentifierName("Table"))
.AddArgumentListArguments(
AttributeArgument(
LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal("Users"))))));
}
/// <summary>
/// 鐢熸垚甯﹀懡鍚嶅弬鏁扮殑鐗规€э細[JsonProperty(PropertyName = "user_id")]
/// </summary>
public AttributeListSyntax GenerateAttributeWithNamedArgument()
{
return AttributeList(
SingletonSeparatedList(
Attribute(IdentifierName("JsonProperty"))
.AddArgumentListArguments(
AttributeArgument(
LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal("user_id")))
.WithNameEquals(
NameEquals(IdentifierName("PropertyName"))))));
}
}鐢熸垚鎺ュ彛
csharp
/// <summary>
/// 鐢熸垚鎺ュ彛鐨勭ず渚?
/// </summary>
public class InterfaceGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曟帴鍙?
/// public interface IRepository { }
/// </summary>
public InterfaceDeclarationSyntax GenerateSimpleInterface()
{
return InterfaceDeclaration("IRepository")
.AddModifiers(Token(SyntaxKind.PublicKeyword));
}
/// <summary>
/// 鐢熸垚甯︽柟娉曠殑鎺ュ彛
/// </summary>
public InterfaceDeclarationSyntax GenerateInterfaceWithMethods()
{
return InterfaceDeclaration("IRepository")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddMembers(
MethodDeclaration(
PredefinedType(Token(SyntaxKind.VoidKeyword)),
"Save")
.AddParameterListParameters(
Parameter(Identifier("entity"))
.WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}
/// <summary>
/// 鐢熸垚娉涘瀷鎺ュ彛
/// </summary>
public InterfaceDeclarationSyntax GenerateGenericInterface()
{
return InterfaceDeclaration("IRepository")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(TypeParameter("T"))
.AddConstraintClauses(
TypeParameterConstraintClause("T")
.AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint)));
}
}鐢熸垚鏋氫妇
csharp
/// <summary>
/// 鐢熸垚鏋氫妇鐨勭ず渚?
/// </summary>
public class EnumGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曟灇涓?
/// </summary>
public EnumDeclarationSyntax GenerateSimpleEnum()
{
return EnumDeclaration("Status")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddMembers(
EnumMemberDeclaration("Active"),
EnumMemberDeclaration("Inactive"),
EnumMemberDeclaration("Pending"));
}
/// <summary>
/// 鐢熸垚甯﹀€肩殑鏋氫妇
/// </summary>
public EnumDeclarationSyntax GenerateEnumWithValues()
{
return EnumDeclaration("ErrorCode")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddMembers(
EnumMemberDeclaration("Success")
.WithEqualsValue(
EqualsValueClause(
LiteralExpression(
SyntaxKind.NumericLiteralExpression,
Literal(0)))),
EnumMemberDeclaration("NotFound")
.WithEqualsValue(
EqualsValueClause(
LiteralExpression(
SyntaxKind.NumericLiteralExpression,
Literal(404)))));
}
}瀛楃涓叉彃鍊?vs SyntaxFactory
浼樼己鐐瑰姣?
瀛楃涓叉彃鍊兼柟寮?
浼樼偣锛?
- 鉁?绠€鍗曠洿瑙傦紝鏄撲簬鐞嗚В
- 鉁?蹇€熷師鍨嬪紑鍙?
- 鉁?閫傚悎绠€鍗曠殑浠g爜鐢熸垚
缂虹偣锛?
- 鉂?闅句互缁存姢澶嶆潅鐨勪唬鐮佺粨鏋?
- 鉂?缂哄皯璇硶楠岃瘉
- 鉂?鏍煎紡鍖栧洶闅?
csharp
// 瀛楃涓叉彃鍊肩ず渚?
public string GenerateClassUsingString(string className)
{
return $@"
public class {className}
{{
public string Name {{ get; set; }}
}}";
}SyntaxFactory 鏂瑰紡
浼樼偣锛?
- 鉁?绫诲瀷瀹夊叏锛岀紪璇戞椂妫€鏌?
- 鉁?鏄撲簬缁存姢鍜岄噸鏋?
- 鉁?鑷姩鏍煎紡鍖?
- 鉁?鏀寔澶嶆潅鐨勪唬鐮佺粨鏋?
缂虹偣锛?
- 鉂?瀛︿範鏇茬嚎闄″抄
- 鉂?浠g爜鍐楅暱
鐪熷疄浣跨敤鍦烘櫙
鍦烘櫙 1: DTO 绫荤敓鎴愬櫒
涓烘暟鎹簱琛ㄨ嚜鍔ㄧ敓鎴?DTO锛圖ata Transfer Object锛夌被銆?
csharp
/// <summary>
/// DTO 绫荤敓鎴愬櫒
/// </summary>
public class DtoGenerator
{
public class ColumnInfo
{
public string Name { get; set; }
public string Type { get; set; }
public bool IsNullable { get; set; }
}
/// <summary>
/// 鐢熸垚 DTO 绫?
/// </summary>
public CompilationUnitSyntax GenerateDto(
string tableName,
List<ColumnInfo> columns)
{
var className = $"{tableName}Dto";
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword));
foreach (var column in columns)
{
var typeName = column.IsNullable ? $"{column.Type}?" : column.Type;
var property = PropertyDeclaration(
ParseTypeName(typeName),
Identifier(column.Name))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
classDecl = classDecl.AddMembers(property);
}
var namespaceDecl = NamespaceDeclaration(ParseName("MyApp.Dtos"))
.AddMembers(classDecl);
return CompilationUnit()
.AddUsings(UsingDirective(ParseName("System")))
.AddMembers(namespaceDecl)
.NormalizeWhitespace();
}
}鍦烘櫙 2: Builder 妯″紡鐢熸垚鍣?
涓虹被鑷姩鐢熸垚 Builder 妯″紡浠g爜銆?
csharp
/// <summary>
/// Builder 妯″紡鐢熸垚鍣?
/// </summary>
public class BuilderPatternGenerator
{
public class PropertyInfo
{
public string Name { get; set; }
public string Type { get; set; }
}
/// <summary>
/// 涓虹被鐢熸垚 Builder
/// </summary>
public ClassDeclarationSyntax GenerateBuilder(
string targetClassName,
List<PropertyInfo> properties)
{
var builderClassName = $"{targetClassName}Builder";
var builderClass = ClassDeclaration(builderClassName)
.AddModifiers(Token(SyntaxKind.PublicKeyword));
// 娣诲姞绉佹湁瀛楁
foreach (var prop in properties)
{
var field = FieldDeclaration(
VariableDeclaration(ParseTypeName(prop.Type))
.AddVariables(
VariableDeclarator(Identifier($"_{ToCamelCase(prop.Name)}"))))
.AddModifiers(Token(SyntaxKind.PrivateKeyword));
builderClass = builderClass.AddMembers(field);
}
// 娣诲姞 With 鏂规硶
foreach (var prop in properties)
{
var withMethod = GenerateWithMethod(builderClassName, prop);
builderClass = builderClass.AddMembers(withMethod);
}
return builderClass;
}
private MethodDeclarationSyntax GenerateWithMethod(
string builderClassName,
PropertyInfo property)
{
var fieldName = $"_{ToCamelCase(property.Name)}";
var paramName = ToCamelCase(property.Name);
return MethodDeclaration(
IdentifierName(builderClassName),
$"With{property.Name}")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddParameterListParameters(
Parameter(Identifier(paramName))
.WithType(ParseTypeName(property.Type)))
.WithBody(Block(
ExpressionStatement(
AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
IdentifierName(fieldName),
IdentifierName(paramName))),
ReturnStatement(ThisExpression())));
}
private string ToCamelCase(string name)
{
if (string.IsNullOrEmpty(name)) return name;
return char.ToLower(name[0]) + name.Substring(1);
}
}甯歌闂瑙g瓟锛團AQ锛?
Q1: 濡備綍鐢熸垚甯﹀懡鍚嶇┖闂寸殑瀹屾暣浠g爜鏂囦欢锛?
**绛?*: 浣跨敤 CompilationUnit 鍜?NamespaceDeclaration锛?
csharp
var compilationUnit = CompilationUnit()
.AddUsings(UsingDirective(ParseName("System")))
.AddMembers(
NamespaceDeclaration(ParseName("MyNamespace"))
.AddMembers(classDeclaration))
.NormalizeWhitespace();Q2: 濡備綍涓虹敓鎴愮殑浠g爜娣诲姞 XML 鏂囨。娉ㄩ噴锛?
**绛?*: 浣跨敤 WithLeadingTrivia 娣诲姞娉ㄩ噴锛?
csharp
var classDecl = ClassDeclaration("MyClass")
.WithLeadingTrivia(
TriviaList(
Comment("/// <summary>"),
CarriageReturnLineFeed,
Comment("/// 鎴戠殑绫?),
CarriageReturnLineFeed,
Comment("/// </summary>"),
CarriageReturnLineFeed));Q3: 濡備綍鐢熸垚 async/await 浠g爜锛?
**绛?*: 浣跨敤 AsyncKeyword 淇グ绗﹀拰 AwaitExpression锛?
csharp
var method = MethodDeclaration(
GenericName("Task")
.AddTypeArgumentListArguments(
PredefinedType(Token(SyntaxKind.IntKeyword))),
"GetValueAsync")
.AddModifiers(
Token(SyntaxKind.PublicKeyword),
Token(SyntaxKind.AsyncKeyword))
.WithBody(Block(
ReturnStatement(
AwaitExpression(
InvocationExpression(
IdentifierName("SomeAsyncMethod"))))));Q4: 濡備綍鐢熸垚 Lambda 琛ㄨ揪寮忥紵
**绛?*: 浣跨敤 SimpleLambdaExpression锛?
csharp
// 鐢熸垚锛歺 => x * 2
var lambda = SimpleLambdaExpression(
Parameter(Identifier("x")),
BinaryExpression(
SyntaxKind.MultiplyExpression,
IdentifierName("x"),
LiteralExpression(
SyntaxKind.NumericLiteralExpression,
Literal(2))));Q5: 濡備綍鐢熸垚 record 绫诲瀷锛圕# 9.0+锛夛紵
**绛?*: 浣跨敤 RecordDeclaration锛?
csharp
// 鐢熸垚锛歱ublic record Person(string Name, int Age);
var record = RecordDeclaration(
Token(SyntaxKind.RecordKeyword),
"Person")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.WithParameterList(
ParameterList(
SeparatedList(new[]
{
Parameter(Identifier("Name"))
.WithType(PredefinedType(Token(SyntaxKind.StringKeyword))),
Parameter(Identifier("Age"))
.WithType(PredefinedType(Token(SyntaxKind.IntKeyword)))
})))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));馃挕 鏈€浣冲疄璺?
瀹炶返 1: 浣跨敤杈呭姪鏂规硶灏佽甯歌妯″紡
csharp
// 鉁?濂斤細灏佽甯歌妯″紡
public static PropertyDeclarationSyntax CreateAutoProperty(
string typeName,
string propertyName)
{
return PropertyDeclaration(
ParseTypeName(typeName),
Identifier(propertyName))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}瀹炶返 2: 浣跨敤鏋勫缓鍣ㄦā寮忕粍缁囧鏉備唬鐮?
csharp
// 鉁?濂斤細浣跨敤鏋勫缓鍣ㄦā寮?
var classDecl = new ClassBuilder()
.WithName("Person")
.WithModifier("public")
.AddProperty("string", "Name")
.AddProperty("int", "Age")
.Build();瀹炶返 3: 濮嬬粓鏍煎紡鍖栫敓鎴愮殑浠g爜
csharp
// 鉁?濂斤細鏍煎紡鍖栦唬鐮?
var code = classDecl.NormalizeWhitespace().ToFullString();鈿狅笍 甯歌閿欒
閿欒 1: 蹇樿娣诲姞绫诲瀷绾︽潫
闂: 娉涘瀷绫荤己灏戝繀瑕佺殑绾︽潫銆?
csharp
// 鉂?閿欒锛氱己灏戠害鏉?
var genericClass = ClassDeclaration("Repository")
.AddTypeParameterListParameters(TypeParameter("T"));瑙e喅鏂规: 娣诲姞绫诲瀷绾︽潫銆?
csharp
// 鉁?姝g‘锛氭坊鍔犵害鏉?
var genericClass = ClassDeclaration("Repository")
.AddTypeParameterListParameters(TypeParameter("T"))
.AddConstraintClauses(
TypeParameterConstraintClause("T")
.AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint)));閿欒 2: 鐗规€у弬鏁伴敊璇?
闂: 鐗规€у弬鏁扮被鍨嬫垨鏍煎紡閿欒銆?
csharp
// 鉂?閿欒锛氬弬鏁扮被鍨嬮敊璇?
var attribute = Attribute(IdentifierName("Table"))
.AddArgumentListArguments(
AttributeArgument(IdentifierName("Users"))); // 搴旇鏄瓧绗︿覆瀛楅潰閲?瑙e喅鏂规: 浣跨敤姝g‘鐨勫弬鏁扮被鍨嬨€?
csharp
// 鉁?姝g‘锛氫娇鐢ㄥ瓧绗︿覆瀛楅潰閲?
var attribute = Attribute(IdentifierName("Table"))
.AddArgumentListArguments(
AttributeArgument(
LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal("Users"))));馃敆 鐩稿叧鏂囨。
- 杩斿洖绱㈠紩
- SyntaxFactory 鍩虹 - 瀛︿範鍩虹鐭ヨ瘑
- 浠g爜鏋勫缓妯″紡 - 瀛︿範鏋勫缓妯″紡
- 鏍煎紡鍖栧拰缇庡寲 - 瀛︿範浠g爜鏍煎紡鍖?
- [鏈€浣冲疄璺礭(./best-practices.md) - 鎺屾彙鏈€浣冲疄璺?
鍏朵粬鐩稿叧鏂囨。
- 璇箟妯″瀷 API - 绗﹀彿鍜岀被鍨嬬郴缁?
- 澧為噺鐢熸垚鍣?API - 鎬ц兘浼樺寲
馃摎 涓嬩竴姝?
瀛︿範瀹屾湰鏂囨。鍚庯紝寤鸿缁х画瀛︿範锛?
- 浠g爜鏋勫缓妯″紡 - 瀛︿範濡備綍缁勭粐澶嶆潅鐨勪唬鐮佺敓鎴愰€昏緫
- [鏈€浣冲疄璺礭(./best-practices.md) - 鎺屾彙浠g爜鐢熸垚鐨勬渶浣冲疄璺靛拰鎬ц兘浼樺寲
- 瀹炴垬绀轰緥 - 鏌ョ湅瀹屾暣鐨勬簮鐢熸垚鍣ㄧず渚?
**鏈€鍚庢洿鏂?*: 2026-02-05
鏂囨。鐗堟湰: 1.0
澶嶆潅缁撴瀯鐢熸垚
鐢熸垚绫?
csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勭被
/// </summary>
public class ClassGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曠殑 POCO 绫?
/// </summary>
public ClassDeclarationSyntax GeneratePocoClass(
string className,
Dictionary<string, string> properties)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword));
// 娣诲姞灞炴€?
foreach (var prop in properties)
{
var property = PropertyDeclaration(
ParseTypeName(prop.Value),
Identifier(prop.Key))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
classDecl = classDecl.AddMembers(property);
}
return classDecl;
}
/// <summary>
/// 鐢熸垚甯︽瀯閫犲嚱鏁扮殑绫?
/// </summary>
public ClassDeclarationSyntax GenerateClassWithConstructor(
string className,
Dictionary<string, string> parameters)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword));
// 娣诲姞瀛楁
foreach (var param in parameters)
{
var field = FieldDeclaration(
VariableDeclaration(ParseTypeName(param.Value))
.AddVariables(
VariableDeclarator(Identifier($"_{param.Key}"))))
.AddModifiers(
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.ReadOnlyKeyword));
classDecl = classDecl.AddMembers(field);
}
// 鍒涘缓鏋勯€犲嚱鏁?
var constructor = ConstructorDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddParameterListParameters(
parameters.Select(p =>
Parameter(Identifier(p.Key))
.WithType(ParseTypeName(p.Value)))
.ToArray())
.WithBody(Block(
parameters.Select(p =>
ExpressionStatement(
AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
IdentifierName($"_{p.Key}"),
IdentifierName(p.Key))))
.ToArray()));
classDecl = classDecl.AddMembers(constructor);
return classDecl;
}
/// <summary>
/// 鐢熸垚瀹炵幇鎺ュ彛鐨勭被
/// </summary>
public ClassDeclarationSyntax GenerateClassWithInterface(
string className,
string interfaceName)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddBaseListTypes(
SimpleBaseType(IdentifierName(interfaceName)));
return classDecl;
}
/// <summary>
/// 鐢熸垚缁ф壙鍩虹被鐨勭被
/// </summary>
public ClassDeclarationSyntax GenerateClassWithBaseClass(
string className,
string baseClassName)
{
var classDecl = ClassDeclaration(className)
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddBaseListTypes(
SimpleBaseType(IdentifierName(baseClassName)));
return classDecl;
}
}鐢熸垚鏂规硶
csharp
/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勬柟娉?
/// </summary>
public class MethodGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曠殑鏂规硶
/// </summary>
public MethodDeclarationSyntax GenerateSimpleMethod()
{
// 鐢熸垚锛歱ublic void DoSomething() { }
return MethodDeclaration(
PredefinedType(Token(SyntaxKind.VoidKeyword)),
Identifier("DoSomething"))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.WithBody(Block());
}
/// <summary>
/// 鐢熸垚甯﹀弬鏁扮殑鏂规硶
/// </summary>
public MethodDeclarationSyntax GenerateMethodWithParameters()
{
// 鐢熸垚锛歱ublic int Add(int a, int b) { return a + b; }
return MethodDeclaration(
PredefinedType(Token(SyntaxKind.IntKeyword)),
Identifier("Add"))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddParameterListParameters(
Parameter(Identifier("a"))
.WithType(PredefinedType(Token(SyntaxKind.IntKeyword))),
Parameter(Identifier("b"))
.WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
.WithBody(Block(
ReturnStatement(
BinaryExpression(
SyntaxKind.AddExpression,
IdentifierName("a"),
IdentifierName("b")))));
}
}鐢熸垚灞炴€?
csharp
/// <summary>
/// 鐢熸垚鍚勭绫诲瀷鐨勫睘鎬?
/// </summary>
public class PropertyGeneration
{
/// <summary>
/// 鐢熸垚鑷姩灞炴€?
/// </summary>
public PropertyDeclarationSyntax GenerateAutoProperty(
string typeName,
string propertyName)
{
// 鐢熸垚锛歱ublic string Name { get; set; }
return PropertyDeclaration(
ParseTypeName(typeName),
Identifier(propertyName))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}
/// <summary>
/// 鐢熸垚鍙灞炴€?
/// </summary>
public PropertyDeclarationSyntax GenerateReadOnlyProperty(
string typeName,
string propertyName)
{
// 鐢熸垚锛歱ublic string Name { get; }
return PropertyDeclaration(
ParseTypeName(typeName),
Identifier(propertyName))
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}
}鐢熸垚娉涘瀷绫?
csharp
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 鐢熸垚娉涘瀷绫荤殑绀轰緥
/// </summary>
public class GenericClassGeneration
{
/// <summary>
/// 鐢熸垚娉涘瀷绫伙細public class Container<T> { }
/// </summary>
public ClassDeclarationSyntax GenerateGenericClass()
{
return ClassDeclaration("Container")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(
TypeParameter("T"));
}
/// <summary>
/// 鐢熸垚甯︾害鏉熺殑娉涘瀷绫?
/// public class Repository<T> where T : class, new() { }
/// </summary>
public ClassDeclarationSyntax GenerateGenericClassWithConstraints()
{
return ClassDeclaration("Repository")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(
TypeParameter("T"))
.AddConstraintClauses(
TypeParameterConstraintClause("T")
.AddConstraints(
ClassOrStructConstraint(SyntaxKind.ClassConstraint),
ConstructorConstraint()));
}
/// <summary>
/// 鐢熸垚澶氫釜绫诲瀷鍙傛暟鐨勬硾鍨嬬被
/// public class Pair<TKey, TValue> { }
/// </summary>
public ClassDeclarationSyntax GenerateMultipleTypeParametersClass()
{
return ClassDeclaration("Pair")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(
TypeParameter("TKey"),
TypeParameter("TValue"));
}
}鐢熸垚鐗规€э紙Attributes锛?
csharp
/// <summary>
/// 鐢熸垚鐗规€х殑绀轰緥
/// </summary>
public class AttributeGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曠壒鎬э細[Serializable]
/// </summary>
public AttributeListSyntax GenerateSimpleAttribute()
{
return AttributeList(
SingletonSeparatedList(
Attribute(IdentifierName("Serializable"))));
}
/// <summary>
/// 鐢熸垚甯﹀弬鏁扮殑鐗规€э細[Table("Users")]
/// </summary>
public AttributeListSyntax GenerateAttributeWithArgument()
{
return AttributeList(
SingletonSeparatedList(
Attribute(IdentifierName("Table"))
.AddArgumentListArguments(
AttributeArgument(
LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal("Users"))))));
}
/// <summary>
/// 鐢熸垚甯﹀懡鍚嶅弬鏁扮殑鐗规€э細[JsonProperty(PropertyName = "user_id")]
/// </summary>
public AttributeListSyntax GenerateAttributeWithNamedArgument()
{
return AttributeList(
SingletonSeparatedList(
Attribute(IdentifierName("JsonProperty"))
.AddArgumentListArguments(
AttributeArgument(
LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal("user_id")))
.WithNameEquals(
NameEquals(IdentifierName("PropertyName"))))));
}
/// <summary>
/// 涓虹被娣诲姞澶氫釜鐗规€?
/// </summary>
public ClassDeclarationSyntax AddAttributesToClass(
ClassDeclarationSyntax classDecl,
params AttributeListSyntax[] attributes)
{
return classDecl.AddAttributeLists(attributes);
}
}鐢熸垚鎺ュ彛
csharp
/// <summary>
/// 鐢熸垚鎺ュ彛鐨勭ず渚?
/// </summary>
public class InterfaceGeneration
{
/// <summary>
/// 鐢熸垚绠€鍗曟帴鍙?
/// public interface IRepository { }
/// </summary>
public InterfaceDeclarationSyntax GenerateSimpleInterface()
{
return InterfaceDeclaration("IRepository")
.AddModifiers(Token(SyntaxKind.PublicKeyword));
}
/// <summary>
/// 鐢熸垚甯︽柟娉曠殑鎺ュ彛
/// public interface IRepository
/// {
/// void Save(object entity);
/// object Load(int id);
/// }
/// </summary>
public InterfaceDeclarationSyntax GenerateInterfaceWithMethods()
{
return InterfaceDeclaration("IRepository")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddMembers(
// void Save(object entity);
MethodDeclaration(
PredefinedType(Token(SyntaxKind.VoidKeyword)),
"Save")
.AddParameterListParameters(
Parameter(Identifier("entity"))
.WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
// object Load(int id);
MethodDeclaration(
PredefinedType(Token(SyntaxKind.ObjectKeyword)),
"Load")
.AddParameterListParameters(
Parameter(Identifier("id"))
.WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}
/// <summary>
/// 鐢熸垚娉涘瀷鎺ュ彛
/// public interface IRepository<T> where T : class
/// {
/// void Save(T entity);
/// T Load(int id);
/// }
/// </summary>
public InterfaceDeclarationSyntax GenerateGenericInterface()
{
return InterfaceDeclaration("IRepository")
.AddModifiers(Token(SyntaxKind.PublicKeyword))
.AddTypeParameterListParameters(TypeParameter("T"))
.AddConstraintClauses(
TypeParameterConstraintClause("T")
.AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint)))
.AddMembers(
MethodDeclaration(
PredefinedType(Token(SyntaxKind.VoidKeyword)),
"Save")
.AddParameterListParameters(
Parameter(Identifier("entity"))
.WithType(IdentifierName("T")))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
MethodDeclaration(
IdentifierName("T"),
"Load")
.AddParameterListParameters(
Parameter(Identifier("id"))
.WithType(PredefinedType(Token(SyntaxKind.IntKeyword))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}
}
---
## 下一步
继续阅读 [Part 2](./syntax-factory-advanced-part2.md)
---
*最后更新: 2025-01-21*