我从https://msdn.microsoft.com/en-us/magazine/mt707527.aspx得到了以下来源,它使用Roslyn生成类:
// Get a workspace
var workspace = new AdhocWorkspace();
// Get the SyntaxGenerator for the specified language
var generator = SyntaxGenerator.GetGenerator(workspace, LanguageNames.CSharp);
// Create using/Imports directives
var usingDirectives = generator.NamespaceImportDeclaration("System");
// Generate two private fields
var lastNameField = generator.FieldDeclaration("_lastName",
generator.TypeExpression(SpecialType.System_String),
Accessibility.Private);
var firstNameField = generator.FieldDeclaration("_firstName",
generator.TypeExpression(SpecialType.System_String),
Accessibility.Private);
// Generate two properties with explicit get/set
var lastNameProperty = generator.PropertyDeclaration("LastName",
generator.TypeExpression(SpecialType.System_String), Accessibility.Public,
getAccessorStatements: new SyntaxNode[]
{ generator.ReturnStatement(generator.IdentifierName("_lastName")) },
setAccessorStatements: new SyntaxNode[]
{ generator.AssignmentStatement(generator.IdentifierName("_lastName"),
generator.IdentifierName("value"))});
var firstNameProperty = generator.PropertyDeclaration("FirstName",
generator.TypeExpression(SpecialType.System_String),
Accessibility.Public,
getAccessorStatements: new SyntaxNode[]
{ generator.ReturnStatement(generator.IdentifierName("_firstName")) },
setAccessorStatements: new SyntaxNode[]
{ generator.AssignmentStatement(generator.IdentifierName("_firstName"),
generator.IdentifierName("value")) });
// Generate parameters for the class' constructor
var constructorParameters = new SyntaxNode[] {
generator.ParameterDeclaration("LastName",
generator.TypeExpression(SpecialType.System_String)),
generator.ParameterDeclaration("FirstName",
generator.TypeExpression(SpecialType.System_String)) };
// Generate the constructor's method body
var constructorBody = new SyntaxNode[] {
generator.AssignmentStatement(generator.IdentifierName("_lastName"),
generator.IdentifierName("LastName")),
generator.AssignmentStatement(generator.IdentifierName("_firstName"),
generator.IdentifierName("FirstName"))};
// Generate the class' constructor
var constructor = generator.ConstructorDeclaration("Person",
constructorParameters, Accessibility.Public,
statements: constructorBody);
// An array of SyntaxNode as the class members
var members = new SyntaxNode[] { lastNameField,
firstNameField, lastNameProperty, firstNameProperty,
constructor };
// Generate the class
var classDefinition = generator.ClassDeclaration(
"Person", typeParameters: null,
accessibility: Accessibility.Public,
modifiers: DeclarationModifiers.Abstract,
baseType: null,
members: members);
generator.AddBaseType(classDefinition, generator.IdentifierName("PersonBase"));
// Declare a namespace
var namespaceDeclaration = generator.NamespaceDeclaration("MyTypes", classDefinition);
// Get a CompilationUnit (code file) for the generated code
var newNode = generator.CompilationUnit(usingDirectives, namespaceDeclaration).
NormalizeWhitespace();
StringBuilder sb = new StringBuilder();
using (StringWriter writer = new StringWriter(sb))
{
newNode.WriteTo(writer);
Console.Write(writer.ToString());
};
一切正常。现在,我需要生成具有名为“PersonBase”
的基类的Person类我尝试使用下面的代码段,但它不会产生预期的结果:
generator.AddBaseType(classDefinition, generator.IdentifierName("PersonBase"));
我做错了什么?
我们非常感谢您的帮助。
感谢。
答案 0 :(得分:2)
找到解决方案。
它似乎与Roslyn对象的不可变特性有关:
var baseNode = generator.IdentifierName("PersonBase");
// Generate the class
var classDefinition = generator.ClassDeclaration(
"Person", typeParameters: null,
accessibility: Accessibility.Public,
modifiers: DeclarationModifiers.Abstract,
baseType: baseNode,
members: members);
感谢。