【问题标题】:Is there a way to generate function overloads in C#?有没有办法在 C# 中生成函数重载?
【发布时间】:2020-12-12 23:49:12
【问题描述】:

上下文:

我正在用 C# 实现一个 BigRational 结构,它需要各种算术和比较重载。由于使用了var,许多重载中的代码看起来完全相同。最重要的是,我收到了 CA2225 的警告,其中指出各种运营商需要一种“友好的替代命名”方法。见https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2225

由于许多算术运算符都被重载了

  • (BigRational, BigRational) -> BigRational
  • (BigRational, BigInteger) -> BigRational
  • (BigInteger, BigRational) -> BigRational
  • (BigRational,长)-> BigRational
  • (long, BigRational) -> BigRational
  • (BigRational, ulong) -> BigRational
  • (ulong, BigRational) -> BigRational

和比较运算符

  • (BigRational, BigRational) -> bool
  • (BigRational, BigInteger) -> bool
  • (BigInteger, BigRational) -> bool
  • (BigRational,长)-> bool
  • (long, BigRational) -> bool
  • (BigRational, ulong) -> bool
  • (ulong, BigRational) -> bool

这会导致大量重复代码和样板。

问题:

有没有简单的方法来使用 C# 9 样式生成器来实现这个?

侧面思考:

如果 C# 能够在语言中内置重载生成功能,那就太好了

public static BigRational Add<T>(BigRational augend, T addend)
    where T overloads: BigInteger, long, ulong
{
    // use var in code...
}

等价于

public static BigRational Add(BigRational augend, BigInteger addend)
{
}

public static BigRational Add(BigRational augend, long addend)
{
}

public static BigRational Add(BigRational augend, ulong addend)
{
}

这也允许人们为不共享基类或接口但具有非常相似的 API 的类型编写单个函数。

【问题讨论】:

标签: c# code-generation c#-9.0


【解决方案1】:

这是您可以编写的source generator 的想法,它可以让您在一般情况下解决这个问题。我不打算编写源代码生成器,因为那会是相当多的工作,但我会重点介绍它的设计。

你会这样写你的类:

public partial struct BigRational
{
    public static BigRational Add(BigRational augend, [GenerateOverloadsFor(typeof(long), typeof(ulong ))] BigInteger addend)
    {
    }
}

然后源生成器将检测GenerateOverloadsForAttribute 的用法并生成以下内容:

partial struct BigRational
{
    public static BigRational Add(BigRational augend, long addend)
    {
    }

    public static BigRational Add(BigRational augend, ulong addend)
    {
    }
}

虽然为这种特定情况编写源代码生成器不太值得,但希望该解决方案足够通用以适用于其他用例。

为了让您的源代码生成器简单明了,它可能只是将代码直接从“模板”复制到生成的重载中。这意味着您必须仔细编写代码,以便它适用于所有重载,否则您将收到编译时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 2015-05-05
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    相关资源
    最近更新 更多