Числа с плавающей запятой, хранящиеся в компьютере, состоят из двух частей: целого и экспоненты, в которых база берется и умножается на целую часть.
Если компьютер работал в базе 10, 0.1
будет 1 x 10⁻¹
, 0.2
будет 2 x 10⁻¹
, а 0.3
будет 3 x 10⁻¹
. Целочисленная математика проста и точна, поэтому добавление 0.1 + 0.2
, очевидно, приведет к 0.3
.
Компьютеры обычно не работают в базе 10, они работают в базе 2. Вы все равно можете получить точные результаты для некоторые значения, например 0.5
, равны 1 x 2⁻¹
, а 0.25
- 1 x 2⁻²
, а их добавление приводит к 3 x 2⁻²
или 0.75
. Точно.
Проблема связана с числами, которые могут быть представлены точно в базе 10, но не в базе 2. Эти цифры должны округляться до их ближайшего эквивалента. Предполагая, что для 64-битного формата с плавающей точкой IEEE используется очень общий формат, ближайшим номером к 0.1
является 3602879701896397 x 2⁻⁵⁵
, а ближайшим номером к 0.2
является 7205759403792794 x 2⁻⁵⁵
; добавление их результатов в 10808639105689191 x 2⁻⁵⁵
или точное десятичное значение 0.3000000000000000444089209850062616169452667236328125
. Номера с плавающей запятой, как правило, округлены для отображения.
T может быть любым типом. Я хочу, чтобы иметь возможность создавать экземпляры ICollectionWrapper без необходимости регистрировать все возможные комбинации T.
blockquote>Это то, для чего нужны реестры. Некоторые IOC называют метод как
RegisterGeneric
, чтобы сделать его самоочевидным (например, autofac), но единство сохраняет его только перегрузкойRegisterType
.container.RegisterType(typeof(ICollectionWrapper<>), typeof(CollectionWrapper<>), new TransientLifetimeManager());
Также обратите внимание, что ваш инъекционный метод имеет несколько конструкторов. Это само по себе считается анти-шаблоном .
Если вы исправите несколько объектов-конструкторов, над регистрацией будет работать.
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType(typeof(IEmployee<>), typeof(Employee<>), new TransientLifetimeManager());
}