如何生成Roslyn运算符重载

时间:2018-05-25 23:39:59

标签: c# operator-overloading bitwise-operators roslyn

我想利用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();
}

一种较旧的编码习惯,但生成的代码也可以正常工作。

然后,或多或少地为二元运算符冲洗和重复,即BitwiseOrExpressionBitwiseAndExpressionExclusiveOrExpression种。

思考?建议?

谢谢!

1 个答案:

答案 0 :(得分:0)

我找到this little gem,虽然我不会从生成的Roslyn代码中获取结果rote,但它确实揭示了根据您想要生成的代码类型可以利用什么的线索。我会使用它并在行之间读取,即可能有无关的IdentifierNamenew []{...}。但它也显示出类似的线索,我确实需要指定位,即使是需要分号令牌的详细信息,即/* ... */ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))。那种性质的东西。