我想利用Roslyn代码生成生成一元运算符和几个二元运算符,但我想知道如何做到这一点。
假设,Descriptor
带有信息,例如我声明运算符的基础TypeSyntax
。
到目前为止,我已经假设了这些内容:
MemberDeclarationSyntax GenerateUnaryOperatorOverload(string methodName, SyntaxKind kind)
{
const string other = nameof(other);
var otherSyntax = Parameter(Identifier(other))
.WithType(Descriptor.Type)
;
var statementSyntax = ParseStatement($"return {otherSyntax.Identifier.ValueText}?.{methodName}();");
return OperatorDeclaration(Descriptor.Type, Token(kind))
// Assuming I need to specify Public and Static as part of the overload...
.WithModifiers(Create(Token(PublicKeyword)).Add(Token(StaticKeyword)))
.AddParameterListParameters(otherSyntax)
.WithBody(Block(statementSyntax))
;
}
作为C#本地函数...其中methodName
是应该调用的基类中方法的名称,kind
是运算符,例如BitwiseNotExpression
( ?)用于 Ones Complement 运算符。
从字面上看,我想最终得到这样的东西:
public static MyType operator ~(MyType other) => other?.BitwiseNot();
如果我可以使用函数登陆,那么实现的操作符过载就会更好。但是,这将是一个可以接受的结果:
public static MyType operator ~(MyType other)
{
return other?.BitwiseNot();
}
一种较旧的编码习惯,但生成的代码也可以正常工作。
然后,或多或少地为二元运算符冲洗和重复,即BitwiseOrExpression
,BitwiseAndExpression
和ExclusiveOrExpression
种。
思考?建议?
谢谢!
答案 0 :(得分:0)
我找到this little gem,虽然我不会从生成的Roslyn代码中获取结果rote,但它确实揭示了根据您想要生成的代码类型可以利用什么的线索。我会使用它并在行之间读取,即可能有无关的IdentifierName
或new []{...}
。但它也显示出类似的线索,我确实需要指定位,即使是需要分号令牌的详细信息,即/* ... */ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
。那种性质的东西。