Приемлемо ли принятие объекта в качестве параметра?

StackOverflow https://stackoverflow.com/questions/967361

  •  12-09-2019
  •  | 
  •  

Вопрос

Допустим, у меня есть текстовое поле или любая другая форма ввода, которая запрашивает номер социального страхования.Я действительно хочу отметить, что SSN - это чистый пример, о котором я просто подумал прямо сейчас.Эти входные данные, естественно, изначально будут сохранены в виде строки.

string s = Console.ReadLine();

Допустим, я хочу иметь метод, который проверяет SSN, и он мог бы использоваться во всем моем коде в самых разных местах.Черт возьми, я мог бы даже вызвать метод для переменной, которая не была определена с помощью пользовательского ввода.

Приемлемо ли это?

public bool IsValidSSN(Object SSN)
{
int mySSN;
    if(Int.Parse(SSN == false)
    {
    mySSN = Convert.toInt32(SSN);
    }
...
}

Или ты бы, парень настаивать что я запрашиваю определенный тип данных, например

public bool IsValidSSN(int SSN)
{
...
}

и поэтому мне необходимо преобразовать входные данные в правильный тип данных, ПРЕЖДЕ чем я вызову для них метод.

КСТАТИ:Я не спрашиваю, как создать правильный код IsValidSSN :) Я просто хотел привести пример того, что я имел в виду, когда сказал:Могу ли я принять тип данных объекта в качестве параметра или мне следует попытаться избежать этого?

Это было полезно?

Решение

Если вы должны принять объект, у меня, по крайней мере, были бы перегрузки метода, который принимает строго типизированные параметры.Затем пусть варианты объекта будут загружены в эти методы.

public bool IsValidSSN(object ssn) {
  ...
  IsValidSSN(Convert.ToInt32(ssn));
  ...
}

public bool IsValidSSN(int ssn) {
  ...
}

Другие советы

Это ПОЛНОСТЬЮ зависит от вашего дизайна и от того, где вы хотите, чтобы проводилась проверка.Это действительно фундаментально зависит от вашей общей архитектуры и вашей иерархии классов.В любом случае, в этом нет ничего плохого;просто будьте уверены, что это тот способ, который соответствует вашему архитектурному дизайну.

Я не вижу смысла в принятии Объекта в этом случае.Продумайте, как вы ожидаете, что эта функция будет работать.(Очевидно, что вы этого не сделали, поскольку опубликованный вами код не работает).Я думаю, ты планируешь что-то вроде этого:

if (SSN is string)
    SSN = Convert.toInt32(SSN);
else if (SSN is TextBox)
    SSN = Convert.toInt32(SSN.Value);
else /* etc */

Чем это лучше, чем:

 bool isValidSSN(int SSN) { /* real valuation code */ }
 bool IsValidSSN(String SSN)  { return isValidSSN(Convert.toInt32(SSN)); }
 bool IsValidSSN(TextBox SSN)  { return isValidSSN(Convert.toInt32(SSN.Value)); }

Перегруженные методы проще и быстрее, поскольку они в большей степени принимают решение о том, что делать, от времени выполнения до времени компиляции.

В приведенном выше примере гораздо проще создать типизированный IsValidSSN .Как правило, я нахожу, что набор текста уменьшает количество ошибок и гибкость.

При обстоятельствах, в которых гибкость имеет первостепенное значение, использование Object, вероятно, является лучшим выбором, но ожидайте столкнуться с несколькими исключениями столкновения приведения в журналах.

Во всех остальных случаях соблюдайте строгость при вводе текста или пишите его на python.

Лично я бы создал класс SSN и мог бы спросить этот SSN, был ли он действительным или нет.Важно иметь классы, которые представляют участников в вашей бизнес-логике.Это очень похоже, например, на то, что вы могли бы сделать с чем-то, что требует дополнительной проверки, например, с классом кредитной карты.Передача объектов не является лучшим решением, если вы можете избежать этого, и передача чего-то, что является основным в вашей бизнес-логике, в качестве примитива тоже плоха (ваша архитектура делает SSN1 + SSN2 = SSN3 совершенно допустимыми, хотя в бизнес-логике это бессмыслица).

В данном случае я бы сказал, что это было неприемлемо.Что делать, если входные данные содержат тире или какой-либо другой разделяющий символ (например:###-##-####)?Очевидно, что вы не смогли бы разобрать значение как целое, но оно все равно было бы допустимым.Как насчет того, чтобы вместо этого использовать регулярное выражение, чтобы убедиться, что значение соответствует вашему желанию?

Что касается использования типа "Object" в качестве параметра, это полностью допустимо во многих случаях.Фактически, он используется во всей .NET Framework (посмотрите на делегатов событий):

public void Control_MouseOver(object sender, MouseEventArgs e){}

Это был бы простой случай упаковки / распаковки, который действительно был единственным способом выполнения "Общих" операций с переменными до .NET 2.0.

Вы также можете использовать дженерики для решения этой проблемы без необходимости приведения.Если вы создадите интерфейс, который реализует что-то вроде INumeric (я не знаю, является ли это фактическим интерфейсом) или IComparable, вы сможете выполнить операцию более элегантным способом:

общедоступный bool - это VALIDSNN(цифровой SSN){}

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top