Вот демонстрация проблемы:компиляции время проверки вызова метода для нескольких параметров одного и того же типа
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);
Это не должно привести любые накладные расходы в коде, но много печатать. Обертка лучше, потому что она выполняется один раз (создание нового типа легко), но, вероятно, накладные расходы.
Если у вас есть десять параметров, вы можете обернуть каждую группу связанных параметров в одном типе, вы считаете, что? –
Возможно, единственный способ гарантировать, что вы не будете давать неправильный аргумент, - это иметь разные типы для ** каждого ** параметра и ** никогда не использовать их в их развернутой форме. Это будет в основном закрывать один из возможных способов совершения ошибок. Является ли это реалистичным подходом или нет, и может ли он действительно улучшить соотношение дефектов на каждую линию и ремонтопригодность для всей программы [другой вопрос] (http://programmers.stackexchange.com/questions/281827/should-we-define -типы-для-всего). –
@MehrzadChehraz, хорошая идея. Звучит как ответ на меня, я просто должен подумать об этом, дай мне немного времени. – Sinatr