Относительно передачи многих параметров - PullRequest
9 голосов
/ 02 декабря 2008

У меня есть около 8-9 параметров для передачи в функцию, которая возвращает массив. Я хотел бы знать, что лучше передать эти параметры непосредственно в функцию или передать массив? Какой путь будет лучше и почему?

Ответы [ 10 ]

12 голосов
/ 02 декабря 2008

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

public struct user 
{ 
    public string FirstName; 
    public string LastName; 
    public string zilionotherproperties; 
    public bool SearchByLastNameOnly; 
} 
public user[] GetUserData(user usr) 
{ 
    //search for users using passed data and return an array of users. 
} 
6 голосов
/ 02 декабря 2008

Передайте их индивидуально, потому что:

  • это типобезопасный способ.
  • IntelliSense подхватит его в Visual Studio, и когда вы напишите свои вызывающие функции, вы узнаете, что к чему.
  • Так быстрее выполнить.

Если параметр действительно является массивом, тогда передайте массив. Пример:

Для функций, которые выглядят так, используйте эту запись:

Array FireEmployee(string first, string middle, string last, int id) {...}

Для функций, которые выглядят так, используйте массив:

Array FireEmployees(Employee[] unionWorkers) {...}
4 голосов
/ 02 декабря 2008

Ваш сценарий охвачен рефакторингом «Ввести объект параметра» в книге рефакторинга Мартина Фаулера. Книгой стоит владеть, но для тех, кто этого не делает, рефакторинг описан здесь . Также есть предварительный просмотр на сайте издателя и в книгах Google. Рекомендуется заменить параметры не массивом, а новым объектом.

3 голосов
/ 02 декабря 2008

Что касается комментариев Скитса к моему примеру выше, что он будет использовать класс вместо структуры и, возможно, прояснит, где использовать класс и где использовать структуру, я тоже публикую это. Я думаю, что есть и другие, кому это тоже интересно.

Основная причина использования класса, как я мог видеть, заключается в том, что вы можете сделать его неизменным, но это возможно и со структурами?

например:

struct user 
{ 
public user(string Username, string LastName) 
{ 
    _username = Username; 
} 
private string _username; 
public string UserName { 
    get { return _username; } 
} 

}

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

Я нашел это описание различий на сайте http://www.startvbdotnet.com/oop/structure.aspx, и это описание именно так, как я отобразил его в своей голове:

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

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

2 голосов
/ 02 декабря 2008

Если это библиотечный код, который будет широко использоваться, и если некоторые из параметров имеют типичные значения, которые являются кандидатами на значения по умолчанию, то вам следует принять во внимание совет Дэйва Маркла и обеспечить выбор перегрузок с постепенно уменьшающимися параметрами , Этот подход рекомендуется в Руководстве по проектированию Microsoft Framework.

С другой стороны, вы можете получить аналогичный эффект с подходом Стефана, устанавливая значения по умолчанию с инициализаторами членов и используя прогрессию перегрузок ctor.

2 голосов
/ 02 декабря 2008

Я предполагаю, что вы используете C # 4 и можете просто использовать именованные параметры:

FireEmployee(
    first: "Frank",
    middle: "",
    last: "Krueger",
    id: 338);

Они делают код почти таким же читаемым, как VB или Smalltalk. : -)

Если нет, я бы согласился с тем, что сказал Дэйв Маркл.

1 голос
/ 02 декабря 2008

Я бы сказал, передайте их также индивидуально. Мне не нравится идея создания класса, а затем передачи этого класса в качестве аргумента. Это форма связи штампов, что означает, что вносить изменения будет сложнее, поскольку один класс использует другой. А повторное использование одного класса означает, что вам также придется использовать другой класс.

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

1 голос
/ 02 декабря 2008

Если вы действительно не хотите передавать свои аргументы отдельно, я бы предложил создать новый класс, который инкапсулирует все ваши аргументы. Вы можете (в Java и, скорее всего, в C #) объявить открытый внутренний класс внутри класса, содержащего gnarly-метод для этой цели. Это позволяет избежать плавающих классов, которые на самом деле являются просто вспомогательными типами.

0 голосов
/ 02 декабря 2008

Вам действительно нужно 8-9 параметров для одной функции? Мне кажется, что если вам нужно столько параметров, то вы, вероятно, делаете слишком много разных вещей в этой функции. Попробуйте преобразовать код в отдельные функции, чтобы у каждой функции было только одно назначение.

0 голосов
/ 02 декабря 2008

Не передавайте их как массив, если функция не работает с массивом, я бы не стал создавать новую структуру данных для группировки параметров по следующим причинам

  1. Передача новой структуры данных скрывает то, что функция действительно нуждается в качестве ввода (нужна ли ей вся структура данных / ее часть?)

  2. Относительно 1 это усложняет UT (при написании UT необходимо воссоздать всю структуру данных)

  3. Если входные параметры не связаны, вы получите новую структуру данных, которая группирует несвязанные типы данных ни по какой другой причине, кроме как для того, чтобы вызов функции выглядел более аккуратно

  4. Если вы решили передать новую структуру данных в вашу функцию, функция не может использоваться в области, где была определена новая структура данных

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

...