在 C# 中创建函数名称的别名

本文关键字:别名 函数 创建 | 更新日期: 2023-09-27 17:57:08

我想在 C# 中为函数名称创建一个别名。

除了函数重载,还有什么办法吗?

public class Test
{
    public void A()
    {
        ...
    }
}

我想在下面称 B 替换 A。

var test = new Test();
test.B();

在 C# 中创建函数名称的别名

我很

惊讶没有人提到代表。它可能与 C# 中的方法别名一样接近:
class DelegaTest
{
    public string F()
    {
        return null;
    }
    public string F(int arg)
    {
        return arg.ToString();
    }
    public void G(int arg1, int arg2)
    {
    }
    /// <summary>
    /// Delegate for `string F()`
    /// </summary>
    public Func<string> D1 => F;
    /// <summary>
    /// Delegate for `string F(int arg)`
    /// </summary>
    public Func<int, string> D2 => F;
    /// <summary>
    /// Delegate for `void G(int arg1, int arg2)`
    /// </summary>
    public Action<int, int> E => G;
}

您可以使用扩展方法

public static class Extensions 
{
    public static void B(this Test t)
    {
       t.A();
    }
}

但它不是别名。 它是一个包装器。


编辑
ps:我同意你的问题的评论者的观点,如果我们知道你真正想做什么,如果我们理解你试图解决的问题,我们就能给出更好的答案。

我真的看不出产生上述扩展方法的意义。

这太老了,但我有一个关于为什么一个人可能想要为方法名称别名的回应。它一直在发生。因为某些开发人员给方法起了一个没有任何意义的名称,或者它根本无法准确描述该方法的用途。该方法在旧的、经验丰富的解决方案中被多次调用。因此,与其执行由于命名不佳的方法而无法证明的大规模重构和重新测试,不如简单地为其提供一个有意义的别名。这样,新代码将来将正确读取。

即保存了一个网格控件,并且有一个方法名称IsReferenceSelectedSendEmail。该名称意味着该方法将标识网格中用户选择的引用是否为 SendEmail。该方法真正做的是遍历所有引用并确定其中任何一个是否是 SendEmail。

简单的解决方案。将该方法别名为 AnyReferenceIsSendEmail,以便将来的代码正确读取:if ( AnyReferenceIsSendEmail() )...

现在,如果我们能得到一个关键字"除非"来否定 if 条件。

国际 海事 组织

实际上,函数别名在 C# 术语中更像是委托(如 C++ 中的函数指针)。这是其中之一:

public class Test
{
    public void Test()
    {
        B += A;
    }
    public void A()
    {
        ...
    }
    public Action B;
}

但是你必须将其称为 B.Invoke(),因为它是无参数的。如果它有一个或多个参数,这将不是问题。

这有效。

class Program
{
    delegate void B();
    static Test t = new Test();
    static B b = t.A;
    static void Main(string[] args)
    {
        b();
    }
}
class Test
{
    public void A()
    {
    }
}

C# 是面向对象的语言,因此无法创建"函数别名"。您只能使用类进行操作。如前所述,您可以使用扩展方法扩展类,也可以创建派生类并在其中创建新方法,这将调用派生方法:

    class Test
    {
        public void A()
        {
            MessageBox.Show("Function A");
        }
    }
    class Test2: Test
    {
        public void B()
        {
            A();
        }
    }

但是,如果您希望在初始类Test上调用B(),则只有一种方法 - 创建扩展方法。

尽管 C# 不直接支持方法别名,但表达式体成员提供了一个漂亮的解决方案:

interface Schema
{
    void Generate();
    void Regenerate();
}
class PgSchema : Schema
{
    public void Generate()
    {
        Console.WriteLine("Executing original method...");
    }
    public void Regenerate() => Generate();
}
var pgSchema = new PgSchema();
pgSchema.Generate();
pgSchema.Regenerate();
// Prints "Executing original method..." two times.
关于

为什么有人想这样做,这篇文章已经有几条评论。 我目前正在为图形项目实现矢量类型,我使用的需求文档可以互换地引用矢量的大小/长度。 为了提高效率,我宁愿不将 Magnitude() 方法包装在 Length() 方法中,但如果结构理解这两个术语,为了可读性,这似乎很好。

Christian Davén 提到的委托方法可能是我可以看到的最有效的方法,但最好只是将文档添加到方法块中:

/// <summary>
/// Calculate the magnitude / length of a vector, including the W component.
/// </summary>
/// <remarks>
/// This calculation will break down if you try to take the magnitude of a point.
/// </remarks>
/// <returns>The magnitude / length of the vector.</returns>
public float Magnitude()
{
    return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
}
我知道

这很旧,但我确实认为这是一个相关的问题,可以使用 C# 3.0 中可用的委托/Lambda 表达式轻松解决,如果没记错的话,它在 OP 时就已经存在了。

假设我们正在创建一个游戏,该游戏要求我们登录到 xbox live,并且有两个按钮 - 一个用于登录,一个用于切换用户。一个名为 SignIn 的函数将同时处理它们,但这会导致添加onclick处理程序时的可读性较差。

幸运的是,可以使用委托和 Lambda 表达式轻松解决此问题。

下面是SignIn函数:

public static async void SignIn(object coreDispatcher)
{
...
}

这是创建"别名"的 Lambda 表达式

public static async void SwitchUser(object param) => SignIn(param);

现在我可以调用SignInSwitchUser并使用相同的代码,但提供更有意义的代码