c# - 同一类型的多个参数的编译时方法调用验证

标签 c# methods compiler-errors

这里是问题的演示:

class Program
{
    static double Func(double a, double b) { return a * 1000 + b * b; }

    static void Main(string[] args)
    {
        var a = 1.1d;
        var b = 2.2d;
        Console.WriteLine(Func(a, b));
        // this is the problem, function doesn't recognize when a and b
        // "accidentally" exchanged, target is to make this row a compile-time error
        Console.WriteLine(Func(b, a));
    }
}

如果方法有很多参数(例如 double 类型的十个),这就会成为一个问题:

double Func(double parameter1, double parameter2, ..., double parameter10);

问题:有没有办法在调用方法时对参数进行校验,让程序员不容易出错?


如果参数类型不同,这不是问题。我认为将包装到新类型中可能会有所帮助:

class A
{
    private double _value;
    public static implicit operator A(double value) { return new A() { _value = value }; }
    public static implicit operator double(A value) { return value._value; }
}
class B
{
    private double _value;
    public static implicit operator B(double value) { return new B() { _value = value }; }
    public static implicit operator double(B value) { return value._value; }
}

class Program
{
    static double Func(A a, B b) { return a * 1000 + b * b; }

    static void Main(string[] args)
    {
        A a = 1.1d;
        B b = 2.2d;
        Console.WriteLine(Func(a, b));
        Console.WriteLine(Func(b, a)); // compile-time error! yay!
        Console.WriteLine(Func(a, b) + 123.123d - a * 2); // implicit conversion power
        Console.ReadKey();
    }
}

确实如此,但我不确定这种方法是否有效。我怀疑这是否是个好主意。是吗?或者有更好的吗?

如果我总是这样调用方法(使用 named arguments 方法调用),我知道我可以绝对安全

Func(a:a, b:b);

这应该不会带来任何代码开销,但会带来大量输入。包装更好,因为它只完成一次(创建新类型很容易),但它可能有开销。

最佳答案

如果两个参数属于同一类型,则不可能在编译时、运行时或其他方面检测到参数变量的名称与参数名称相对应。这是一个悬而未决的问题,但我会为您提供一些想法。

  • 正如 Mehrzad 建议的那样,考虑按某种类型对参数进行分组。例如,而不是 double Distance(double x1, double y1, double x2, double y2) , 考虑 double Distance(Point p1, Point p2)

  • 一般来说,如果您的方法有超过 4-5 个参数,请考虑重构。也许您的方法试图做太多事情并且逻辑可以划分?

  • 如果您真正想要做的是执行一些检查,例如确保 a < b , 考虑调查 Code contracts .您也可以使用 Debug.Assert() ,但这只在运行时有效。

  • 我不会推荐您建议的那种隐式转换。对我来说,A a = 1.1 感觉很古怪和不直观除了编译时检查参数外,应该没有语义目的。您的最终目标是使代码总体上更易于维护。

关于c# - 同一类型的多个参数的编译时方法调用验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30098331/

相关文章:

c# - 如何确定字符串的大小并压缩它

c# - DataContractJsonSerializer 跳过具有空值的节点

javascript - Jquery each 方法

javascript - JavaScript 中字符串的子类化

java ant compile 在同一个包的同一个目录中找不到类

c# - 使用 Roslyn 和 .NET Core 生成 C# 代码

c# - 如何将 IntPtr 转换为数组?

java - 访问addMouseListener()方法内部的方法

c# - 为什么一个属性被认为是不明确的,而另一个接口(interface)是只设置的?

java - 机器人类 - 未处理的异常类型 AWTException