2015-04-29 5 views
2

Надеюсь, кто-то может пролить свет на этот. У меня есть интерфейс с необязательным параметром. Мы используем Unity. Если я попытаюсь изменить необязательный параметр в реализации метода, он работает напрямую, но объект Unity использует интерфейс по умолчанию, а не по умолчанию реализованный метод.Интерфейс C#, единство и необязательный параметр

Установка:

public interface ITestOptional { 
    string HappyMethod(string input, bool amHappy = false); 
} 

public class TestingOptional : ITestOptional { 
    public string HappyMethod(string input, bool amHappy = true) { 
       if (amHappy) return input + " is Happy!"; 
       return input + " is Not Happy!"; 
    } 
} 

Добавить в Unity:

container.RegisterType<ITestOptional, TestingOptional>(); 

И тест:

//direct call 
var testDirect = new TestingOptional(); 
string happyDirect = testDirect.HappyMethod("Cow", true); //expecting happy - get happy 
string sadDirect = testDirect.HappyMethod("Cow", false); //expecting not happy - get not happy 
string defaultDirect = testDirect.HappyMethod("Cow"); //expecting happy (default) get happy 

//unity 
var testUnity = ServiceLocator.Current.GetInstance<ITestOptional>(); 

string happyUnity = testUnity.HappyMethod("Cow", true); //expecting happy - get happy 
string sadUnity = testUnity.HappyMethod("Cow", false); //expecting not happy - get not happy 
string defaultUnity = testUnity.HappyMethod("Cow"); //expecting happy (default) but get NOT happy. 

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

+1

Я не хочу звучать критически, но кажется, что на самом деле путано иметь эту разницу. – n8wrl

+0

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

ответ

1

ServiceLocator.Current.GetInstance<ITestOptional>(); возвращает компилировать тип ITestOptional, так называют в testUnity.HappyMethod("Cow"); будет преобразован компилятором использовать значение по умолчанию, как указано в интерфейсе.

Аналогичным образом new TestingOptional(); возвращает время компиляции TestingOptional, а компилятор выбирает значение по умолчанию из класса.

Возможное решение (сокр регулировки ожидания/не используя различные значения по умолчанию): вы можете решить, что тип непосредственно с помощью Unity вместо решения interfce (иногда полезно для тестирования):

var directViaContainer = container.Resolve<TestingOptional>(); 

примечание стороны: повторное определение значения по умолчанию в классе, реализующие интерфейс, не являются божественной практикой - вы часто попадаете в этот запутанный код.

+0

Согласитесь с битом «хорошая практика» - значения по умолчанию должны совпадать только по этой причине (запутанный код) - эта путаница побудила меня опубликовать это в первую очередь. Я думаю, что если вы измените значение по умолчанию из интерфейса, он не должен считаться действительным для этого интерфейса, но это личное мнение, которое может быть ошибочным на нескольких уровнях. – imukai

0

Вы должны использовать метод Resolve<T>, из экземпляра IUnityContainer. Для образца:

var testUnity = container.Resolve<ITestOptional>(); 
0

В первом примере, ваш testDirect является экземпляром типа TestingOptional, для которого вы запускаете его перегрузку HappyMethod напрямую, используя это указано значение параметра по умолчанию в true.

В вашем втором примере, ваш testUnity является экземпляром типа ITestOptional и вы вызывать его HappyMethod, который указывает другое значение параметра по умолчанию в false.

Это не связано с тем, как вы создали эти экземпляры. Вы бы это заметили, если бы сделали:

ITestOptional x = new TestingOptional(); 
x.HappyMethod("Cow"); 
1

Это не имеет ничего общего с Unity. Вот как работает компилятор C#. Дополнительные аргументы заполняются компилятором по адресу . Время компиляции. В первом примере вы вызываете метод HappyMethod по конкретному типу, и этот необязательный атрибут помечен true, поэтому компилятор C# заполнит true для вас. Во втором примере, однако, компилятор C# не знает о существовании реализации, поэтому он рассмотрит определение интерфейса. И угадайте, что: этот интерфейс отмечен false.

Смежные вопросы