Замок Windsor является инверсией инструмента управления. Существуют другие как он.
Это может дать Вам объекты с предварительно созданными и предпроводными зависимостями прямо там. весь граф объектов, созданный через отражение и конфигурацию, а не "новый" оператор.
Запускаются здесь: http://tech.groups.yahoo.com/group/altdotnet/message/10434
Предполагает, что у Вас есть электронное письмо, отправляющее класс. EmailSender. Предположите, что у Вас есть другой класс WorkflowStepper. В WorkflowStepper необходимо использовать EmailSender.
Вы могли всегда говорить new EmailSender().Send(emailMessage);
, но что - использование new
- создает ПЛОТНОЕ СОЕДИНЕНИЕ, которое трудно изменить. (это, крошечным является изобретенный пример, в конце концов)
Поэтому, что, если, вместо newing этот плохой парень в WorkflowStepper, Вы просто передали его в конструктора?
Таким образом, кто бы ни назвал его, имел к новому EmailSender.
new WorkflowStepper(emailSender).Step()
Предполагают, что у Вас есть сотни этих небольших классов, которые только несут одну ответственность (google SRP).. и Вы используете несколько из них в WorkflowStepper:
new WorkflowStepper(emailSender, alertRegistry, databaseConnection).Step()
Предполагают не вызывать беспокойство о деталях EmailSender
, когда Вы пишете WorkflowStepper
, или AlertRegistry
Вы просто волнуетесь о беспокойстве, с которым Вы работаете.
Предполагают, что этот целый график (дерево) объектов и зависимостей обеспечен электричеством во ВРЕМЯ ВЫПОЛНЕНИЯ, так, чтобы, когда Вы делаете это:
WorkflowStepper stepper = Container.Get
Вы получаете реальное соглашение WorkflowStepper
со всеми зависимостями, автоматически заполненными, где Вам нужны они.
new
, Это всего происходит - потому что это знает то, чему нужно что.
И можно записать меньше дефектов с лучше разработанным, код DRY тестируемым и повторяемым способом.
Я помню, что это поведение было своего рода изменением в последнюю минуту. В ранних бета-версиях .NET 2.0 Nullable
был «нормальным» типом значения. Упаковка пустого
значения int?
превратила его в упакованный int?
с логическим флагом. Я думаю, что причина, по которой они решили выбрать нынешний подход, заключается в последовательности. Скажите:
int? test = null;
object obj = test;
if (test != null)
Console.WriteLine("test is not null");
if (obj != null)
Console.WriteLine("obj is not null");
В первом подходе (box null
-> boxed Nullable
) вы не получите "test is not null", но получите " объект не равен нулю », что странно.
Кроме того, если бы они поместили обнуляемое значение в boxed-Nullable
:
int? val = 42;
object obj = val;
if (obj != null) {
// Our object is not null, so intuitively it's an `int` value:
int x = (int)obj; // ...but this would have failed.
}
Кроме того, я считаю, что текущее поведение имеет смысл для таких сценариев, как значения базы данных, допускающие обнуление (подумайте, SQL-CLR ... )
Весь смысл предоставления типов, допускающих значение NULL, состоит в том, чтобы упростить работу с переменными, которые не имеют значимого значения. Они не хотели выделять два разных, не связанных между собой типа. int?
должен вести себя более или менее как простой int
. Вот почему C # предоставляет поднятые операторы.
Таким образом, при распаковке типа значения в версию, допускающую значение NULL, среда CLR должна выделить объект
Nullable
, инициализировать поле hasValue значением true и установить для поля значения то же значение, что и в типе значения в штучной упаковке. Это влияет на производительность вашего приложения (выделение памяти во время распаковки).
Это неверно. CLR должна выделить память в стеке для хранения переменной независимо от того, допускает ли она значение NULL. Нет проблем с производительностью при выделении места для дополнительной логической переменной.
Думаю, имеет смысл поместить нулевое значение в пустую ссылку. Наличие значения в рамке, говорящего: «Я знаю, что я был бы Int32
, если бы у меня было значение, но нет», мне кажется неинтуитивным. Лучше перейти от версии типа значения «не значение» (значение с HasValue
как false) к версии ссылочного типа «не значение» (пустая ссылка)
Я считаю это изменение было внесено на основании отзывов сообщества, кстати.
Это также позволяет интересно использовать как
даже для типов значений:
object mightBeADouble = GetMyValue();
double? unboxed = mightBeADouble as double?;
if (unboxed != null)
{
...
}
Это больше соответствует способу "неопределенных преобразований" обрабатывается со ссылочными типами, чем предыдущий:
object mightBeADouble = GetMyValue();
if (mightBeADouble is double)
{
double unboxed = (double) mightBeADouble;
...
}
(Он также может работать лучше, поскольку существует только одна проверка типа времени выполнения.)
Благодаря такому поведению вы получаете то, что коробочная версия реализует все интерфейсы, поддерживаемые базовым типом. (Цель состоит в том, чтобы сделать Nullable
таким же, как int
для всех практических целей.) Упаковка в boxed-Nullable
вместо boxed-int
предотвратит такое поведение.
Со страницы MSDN,
double? d = 44.4;
object iBoxed = d;
// Access IConvertible interface implemented by double.
IConvertible ic = (IConvertible)iBoxed;
int i = ic.ToInt32(null);
string str = ic.ToString();
Также просто получить int из коробочной версии Nullable
- обычно вы не можете распаковать в тип, отличный от исходного src тип.
float f = 1.5f;
object boxed_float = f;
int int_value = (int) boxed_float; // will blow up. Cannot unbox a float to an int, you *must* unbox to a float first.
float? nullableFloat = 1.4f;
boxed_float = nullableFloat;
float fValue = (float) boxed_float; // can unbox a float? to a float Console.WriteLine(fValue);
Здесь вам не нужно знать, была ли исходная версия int или Nullable. (+ вы тоже получаете некоторую производительность; сэкономьте место для хранения логического значения hasValue
, а также в объекте в коробке)
Думаю, это в основном то, что он делает. Приведенное описание включает ваше предложение (т. Е. Упаковка в Nullable
).
Кроме того, после упаковки устанавливается поле hasValue
.