有没有一种方法可以在不提到类型的情况下调用静态函数?

4

简单的问题,我觉得可能是不可能的,但以前曾经惊讶过。

我有一个包含各种数学函数的库,让我们举一个非常简单的例子floorcap:

class MathLib {
    public static double floorcap(double floor, double value, double cap) {
        return Math.Min(Math.Max(floor, value), cap);
    }
}

在另一个类中的另一种方法中,我只想键入
var mat_adjusted = floorcap(1, maturity, 5);

但是这样做行不通,因为它没有在这个类中声明,而是在一个库中。这让我输入


var mat_adjusted = MathLib.floorcap(1, maturity, 5);

添加噪音到代码中,我可以将其缩短为


using m = MyMathLibrary.MathLib;

.. yadayada

var mat_adjusted = m.floorcap(1, maturity, 5);

但是,我希望不必一直输入类名。这种可能性存在吗?我也在使用F#编写代码,习惯了一段时间后就不必拼写类型/模块等。当我需要编写C#代码时,这个东西会让我有些烦恼,因为它分散了实际的重点。
这里有很多函数,当你需要调用几个嵌套的函数时,所有这些点和类名就会增加。我喜欢让我的代码尽可能简洁。
提前感谢,
Gert-Jan

4
好的,使用来自同一类中的方法。 :) - ChaosPandion
1
我不确定为什么你对点符号表示法有这样的问题——MathLib.FloorCap(1, 2, 3) 对我来说看起来非常干净,而且只多了几个字符。 - Ron Warholic
实际上,考虑到扩展方法和“本地包装器”,忘记在示例中提到它们。包装器会增加很多开销,扩展方法也会使代码变得混乱。关键是代码应该尽可能地看起来像非程序员会写下的东西。 - gjvdkamp
@Ron请看这里http://en.wikipedia.org/wiki/Advanced_IRB,例如,还有很多类似的内容。当函数变得更加复杂并开始堆叠时,清晰的代码确实非常重要。 - gjvdkamp
2
不,这是不可能的,而且我认为这是一件好事。在没有上下文的情况下全局公开静态成员将导致各种名称冲突。不要混淆干净的代码和短小的代码。 - H H
显示剩余10条评论
5个回答

5
不,这是不可能的——它必须限定到它所在的范围(显然,如果该事物 您当前上下文的范围内,则可以,但这忽略了问题和目标的要点。)
这是因为没有任何东西直接高于任何类型等级——因此没有“全局调用”的意义,可以说。

1
@Jonathon Dickinson:不是这样的——请看我对InvisibleBacon答案的评论。 - Grant Thomas
我同意@Mr. Disappointment的观点。在类外部是不可能的。其他人所描述的是创建一个新的未经限定的方法,而不是如何调用原始的未经限定的方法。 - James Michael Hare
根据他的问题,可能是指“我不想一直输入类名”,这意味着能够使用本地变量就足够了(并非侮辱,您知道扩展方法是什么吗?)。 - Jonathan Dickinson
无论它编译成什么,只想尽可能轻松地使用它。 - Jonathan Dickinson
我认为我们正在就扩展方法是否是一个好主意进行辩论。然而,问题并不在于此,问题只是关于最小化代码,这正是扩展方法所做的。我同意这并不总是一个好主意。 - InvisibleBacon
显示剩余5条评论

3

有一种方法可以实现这一点,那就是使用扩展方法。例如,如果您在一个静态类中定义了您的示例函数:

static class MathLib
{
    public static double floorcap(this double value, double floor, double cap)
    {
        return Math.Min(Math.Max(floor, value), cap);
    }
}

然后您可以像这样使用它:
var mat_adjusted = maturity.floorcap(1, 5);

你仍然需要对它进行限定:无论是通过静态类名、类型名还是限定调用。 - Grant Thomas
@Mr. Disappointment:是的,但OP想要更少的代码输入;这个方案几乎提供了最少的代码,并且与他所期望的floorcap(1, maturity, 5)示例相当吻合,因为没有来自静态类或命名空间的任何噪音。 - Ron Warholic
@Ron Warholic,你是正确的。现在,除非我经常使用MathLib中的少数几个函数,否则我不会在我的代码中这样做。 - InvisibleBacon
嗨,实际上我考虑过扩展方法,但它们会感觉不同于普通的数学代码。 - gjvdkamp
在这种情况下,我不认为你有其他选择。你必须限定你的函数或者在本地声明它们。请参考Mr. Disappointment的回答。 - InvisibleBacon

1

如果您想节省打字时间,可以将方法存根复制并粘贴到每个客户端类中。

private static double floorcap(double floor, double value, double cap) {
    return MathLib.floorcap(floor, value, cap);
}

2
这是一个维护的噩梦。 - Grant Thomas
2
@Mr. Disappointment - 你必须承认它确实回答了他们的问题。 - ChaosPandion
@ChaosPandion:是的,但它仍然在内部以合格的方式调用该方法。关键是你不是不带限定符地调用MathLib.floorcap,而是调用一个新的未经限定的方法,该方法调用了限定的方法。 - James Michael Hare
@ChaosPandion:确实,表面上看起来是这样,但咬紧牙关。 - Grant Thomas
嗨,谢谢,确实会有所帮助,尽管这不是我正在寻找的“干净利落”的解决方案。没想到这是可能的。 - gjvdkamp
显示剩余2条评论

0
唯一可能给你所需的东西的方法是使用扩展方法来扩展你想要使用的算术类型:
public static class MathLibExt {
  public static double FloorCap(this double value, double floor, double cap) {
    return Math.Min(Math.Max(floor, value), cap);
  }
}

// call like
var value = 25.0;
var capped = value.FloorCap(1, 10);

0

有一些方法可以做到这一点,比如在每个调用你的库的类中定义一个private static方法;然而,我认为最好的解决方案就是克服它,每次都输入类名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接