Глобальный член против передаваемых параметров

У меня есть проект ASP.NET, в котором у меня есть метод с 10 локальными переменными. Этот метод вызывает около 10 других методов. 3 из вызванных методов нуждаются во всех переменных. Считается ли хорошей практикой превращать все эти переменные в глобальные члены, и тогда их не нужно передавать в качестве параметров?

3 c#
10.12.2008 12:49:09
7 ОТВЕТОВ
РЕШЕНИЕ

вместо этого создайте структуру и передайте структуру вместо передачи этих 10 параметров

Например:

public struct user 
{ 
    public string FirstName; 
    public string LastName; 
    public string zilionotherproperties; 
    public bool SearchByLastNameOnly; 
    public datetime date1;
} 
3
10.12.2008 13:07:57
Это должен быть класс, а не структура. И если это была структура, она должна быть неизменной, в противном случае вы требуете много боли. Да, и это должны быть свойства, а не поля - но я согласен с общим подходом (передать объект для государства).
Marc Gravell♦ 10.12.2008 13:14:15
Мне интересно, является ли группирование параметров в классе в большем масштабе (скажем, API с около 50 методами) самым разумным выбором или нет, хорошо ли это, если есть много методов с большим количеством параметров?
lysergic-acid 18.05.2012 21:46:43

Ну, это полностью зависит от того, что вы подразумеваете под «глобальными членами».

Если, учитывая, что вы пишете приложение ASP.NET, вы имеете в виду значения кэша на основе сеанса / приложения, то это зависит. Это влияет на производительность, поэтому вам следует оценить, влияет ли это на ваше приложение.

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

2
10.12.2008 12:52:45

Относятся ли эти переменные друг к другу, или все они, или, возможно, в несколько групп? Если так, заключите их в тип. Таким образом, у вас может быть половина ваших переменных, относящихся к пользователю, и половина, относящаяся к запрошенной операции - и вдруг ваш метод, принимающий 10 переменных, принимает только 2.

Делать вещи глобальными - это почти всегда неправильный путь.

4
10.12.2008 12:57:26

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

public class Foo {
     public string Key {get;set;}
     public decimal Quantity {get;set;}
     // etc
}

И пусть методы принимают этот объект в качестве аргумента. Тогда вы просто создаете экземпляр этого и передаете его.

Глобал - это большое нет-нет; ASP.NET очень многопоточный - это было бы кошмаром. Состояние по запросу возможно, но немного грязно.

8
10.12.2008 13:12:53

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

Я не могу вспомнить точный пример от случая к случаю, но в книге «Руководства по проектированию фреймворка» от Microsoft они явно описывают сценарий, подобный вашему, а также то, как они следовали тому же подходу в .NET Framework.

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

2
10.12.2008 13:00:32

Просто будьте осторожны с боксом. Если вы передаете 10 типов ссылок, это зависит от личных предпочтений.

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

Если вы оставите их как локальные переменные в стеке методов (передавая их как параметры), они останутся в стеке, а не будут помещены в кучу.

1
10.12.2008 16:34:52

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

Однако у вас есть большая серия зависимых методов, каждый из которых действует на общее состояние (не менее 10 значений). Похоже, вы должны разработать класс для обработки этой операции.

Класс будет инкапсулировать поведение и соответствующее состояние, а не будет простым набором свойств (см. Модель анемичной области ).

1
10.12.2008 16:50:51