有没有办法在 C# 中为单个静态(公共)方法添加别名?

Is there a way to alias a single, static (public) method in C#?

提问人:teichert 提问时间:3/18/2021 最后编辑:teichert 更新时间:3/18/2021 访问量:882

问:

除了允许导入命名空间中的所有类型外,C# 中的 using 指令还允许通过别名(例如 )导入单个类型,或者通过 从类型导入所有静态方法。在 C# 规范中,我没有发现任何关于导入单个静态方法的提及。using A = Something.A;using static

问题:有没有其他方法可以实现同样的事情(即通过放置在源文件开头的一指令/语句从外部类型导入单个静态方法)?如果没有,是否有任何书面原因,或者是否有任何证据表明计划在未来允许这样做?

例如,作为想要为特定静态方法添加别名而不是使用类中的所有静态方法(包括重载)的可能动机,请考虑以下代码片段:

using static System.Console; // includes System.Console.WriteLine
using static System.Diagnostics.Debug; // includes System.Diagnostics.Debug.Assert (as desired) and System.Diagnostics.Debug.WriteLine (not desired)

class Program {
   static void Main() {
      Assert(3 + 5 == 8);
      // the following doesn't know which WriteLine to use
      WriteLine("My test passed!"); // error CS0121: The call is ambiguous
   }
}

这是我想要的语法(这是非法的):

using static System.Console;
using static Assert = System.Diagnostics.Debug.Assert;

class Program {
   static void Main() {
      Assert(3 + 5 == 8);
      WriteLine("My test passed!");
   }
}

在类中定义一个调用我想要别名的方法,可以工作,但不允许我将其与另一个 using 指令一起放在文件的顶部:

class Program {
   static void Assert(bool c) { System.Diagnostics.Debug.Assert(c); }
}

以下是一些将某些内容放在文件顶部的失败尝试:

using Assert = System.Diagnostics.Debug.Assert; // error CS0426 (i.e. Assert is not a type)
using static Assert = System.Diagnostics.Debug.Assert; // error CS8085: error CS8085: A 'using static' directive cannot be used to declare an alias
var Assert = System.Diagnostics.Debug.Assert; // error CS0815
System.Action<bool> Assert = System.Diagnostics.Debug.Assert; // error CS1618
System.Action<bool> Assert = (c) => System.Diagnostics.Debug.Assert(c); // error when using Assert: error CS1618
void Assert(bool c) { System.Diagnostics.Debug.Assert(c); } // error when using Assert: error CS8801
C# 静态方法 using 指令

评论

1赞 Rufus L 3/18/2021
你可以编写自己的方法来包装你想要别名的方法......
0赞 teichert 3/18/2021
@RufusL 谢谢;这可能是最好的。据我了解,该方法必须在类内定义,而使用指令是在类外完成的,因此这并不是我所希望/期望的。
0赞 Jeremy Lakeman 3/18/2021
您可以定义一个静态委托,而不是包装器方法。但我根本不推荐任何语句,对于未来的维护者来说,每个方法调用的实际作用以及定义位置不太明显。static Action<bool> Assert = new Action<bool>(Debug.Assert);using static

答:

2赞 John Wu 3/18/2021 #1

没有这种编译时别名,但通过代码自己“别名”是一件简单的事情。

class Program
{
    static void WriteLine(string message) => Console.WriteLine(message);

    static void Main()
    {
        Assert(3 + 5 == 8);
        WriteLine("My test passed!"); 
    }
}
1赞 Orace 3/18/2021 #2

由于方法重载,这种别名并不简单,例如,此处是 Console.WriteLine 重载的列表。

如何消除别名方法与其重载的歧义?

评论

0赞 teichert 3/18/2021
+1 很好的观察,但是当我“使用静态 System.Diagnostics.Debug;”进行构建时,这个问题不是已经处理好了吗?不过,你的观点很好---假设我很乐意导入所有重载,但我只想导入一个名称。
0赞 teichert 3/18/2021
我已经更新了我的描述,以澄清我也对过载感到满意。