Итак, во-первых, резюме вопроса - как это работает?
var dbMigrator = new DbMigrator(new Logger());
Не так ли?
var logger = new Logger();
var dbMigrator = new DbMigrator(logger);
Полностью подробный ответ довольно длинный, поэтому я постараюсь изо всех сил сделать его приятным и легким для подражания. Мы сделаем это, сначала опираясь на выражение и как они работают на C# (более широко, как они работают на любом языке на основе стека), к счастью, это почти все из тех, что вы слышали!)
Выражения, заявления и операции .. что?
Операция: Что-то вроде сложения, вычитания и т.д.
Выражение: кучу операций. 1+2+3
или просто константа, как 1
или "hi!"
заявление: Обычно одно выражения, за которым следует ;
но что-то вроде if
или while
петли также заявление. Если программа была рецептом приготовления пищи, заявление является просто одним из этапов.
Давайте кратко рассмотрим, что в C#:
int totalPrice=1+2*3;
Это одно заявление, и это разбита на операций как это:
- Умножение 2, 3
- Добавить 1
- Задайте результат в локальной переменной, которая называется
totalPrice
Отличный вопрос, чтобы спросить в этот момент, то это:
Так сразу после Multiply 2 by 3
трасс, где находится 6 хранится?
Стек. Подробнее об этом коротко!
Быстрых дополнительные замечания по методам
Метод требует как Hello("all!");
принимать выражения в качестве аргументов. Hello(1+1;);
терпит неудачу, потому что это заявление там. Hello(1+(2*3));
в порядке хотя.
Операции
Каждая операция принимает в любом количестве операндов затем необязательно выводит что-то. Например, операция умножения занимает 2 операнда - A * B - затем выводит все, что было умножено вместе. new Something()
принимает любое количество аргументов конструктора и выводит ссылку на вновь созданный объект.
Вот важная часть.
Выходной сигнал операции всегда поступает в стек. Входы также всегда помещаются в стек.
Так что это за штука?
Полный stack machine не входит в сферу действия здесь - если вас интересует полная информация, то проверьте, например. this wikipedia article. Краткое резюме - все языки на языке C используют эту же концепцию.Давайте вернемся, что C# заявление выше и описать его в операциях стека:
int totalPrice=1+2*3;
Push 2 на стек
Стек теперь только [2]
Нажмите 3 на стоп
Стек теперь [2,3]
Умножить (Извлекает от двух значений из стека и умножает их)
Стек теперь [6]
Нажмите 1 в стек
Стек сейчас [6,1]
Добавить (Отбрасывает два значения из стека, добавляет их вместе)
Стек теперь [7]
Хранить в локальной totalPrice
(выскакивает от значения стека и сохраняет его)
Стек теперь пуста
Замечание: эти операции стека - это то, что генерирует компилятор C#. Это называется CIL or .NET IL.
Вызов стека предупреждение
здоровья! Стол вызовов - это нечто совершенно другое. Это стек вызовов, который может «переполняться».
Как насчет оригинального заявления?
Хорошо, мы надеемся, что мы покрыли достаточно земли для этой части, чтобы иметь больше смысла! Итак, давайте оригинальное заявление:
var dbMigrator = new DbMigrator(new Logger());
Во-первых, new
операция так же, как и любой другой метод вызова - все аргументы в стек, то вызывается метод (выскакивают их всех из стека) и возвращаемое значение затем помещается в стек.
Итак, здесь описывается стиль стека:
New Logger Object (Создает объект Logger на куче и помещает ссылку на него в стеке.Нет арг, так что ничего не поп)
Stack теперь [ссылка регистратор]
New DBMigrator Object (Забирает 1 ARG прочь, толкает ссылку)
стек Теперь [ссылка DBMigrator]
Хранить в местном dbMigrator
Стек теперь пуст
Чтобы действительно цемент, который в, сравнить его с альтернативой (который также является действительным):
var logger = new Logger();
var dbMigrator = new DbMigrator(logger);
Новый Logger Объект
Stack в настоящее время [справочник по регистрации]
Хранить в местной logger
Стек теперь пуст
нагрузки местного logger
Stack теперь [ссылка регистратор]
Новый DbMigrator Объект
Стек теперь [DBMig rator ссылка]
магазин в местном dbMigrator
Стек теперь пуст
Что вы только что узнали: Они оба работают, но второй один немного медленнее - это больше. Глядя на эти операции с стеками, он, кажется, делает что-то совершенно бессмысленное. Это похоже на то, что вы просто положили что-то в шкафчик, а затем сразу же вытащили его снова!
Когда следует использовать местные жители над стеком?
В качестве быстрого примечания стороны, есть языки, которые не имеют местных жителей и используют стек. Они могут быть чрезвычайно оптимизированы и имеют тенденцию идти быстрее, но их также труднее написать.Местные жители являются большими, если вам нужно несколько ссылок на что-то:
Logger logger=new Logger();
// Using it twice!
logger.A();
logger.B();
Если вы только с помощью его один раз, то это вполне допустимо также:
(new Logger()).A();
Бонус раунд: Допустим, что метод A
сделал return this;
, что привело к ссылке на этот объект Logger в стеке снова. Это будет позволять нам сделать это:
(new Logger()).A().B();
Это метод цепочки - это связано с функционального программирования и становится все более распространенным из-за того, как это компактный.
Резюме
Локальные переменные не единственный способ хранения вещей - стек делает это слишком! Вам не нужно отслеживать стек - компилятор делает все это для вас. Вам просто нужно подумать об этих значениях ввода/вывода.
Я не совсем уверен, что понимаю ваш вопрос. Вы спрашиваете, почему, внутри класса и/или конструктора DbMigrator, прежде чем назначить '_logger = logger;', почему у вас нет '_logger = new Logger();'? Пожалуйста, постарайтесь уточнить, о чем именно вы спрашиваете. –
'no object name for logger' - я думаю, вы не имеете в виду _variable_ для регистратора. Это не имеет значения - нет требования, чтобы у вас была локальная переменная, которая ссылается на объект. –
Да, имя переменной для объекта. – schulzey