2015-04-29 56 views
2

希望有人能對此發表一些看法。我有一個可選參數的接口。我們使用Unity。如果我嘗試更改方法實現中的可選參數,它將直接運行,但Unity對象使用接口的默認值 - 而不是實現的方法的默認值。C#接口,Unity和可選參數

設置:

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. 

爲什麼統一性對象使用虛假的可選參數的任何想法時,實現使用真正?

+1

我不想聽起來很關鍵,但看起來*真的很迷惑,有這種差異。 – n8wrl

+0

我完全贊同混淆因素。我計劃讓默認匹配,然後好奇心越來越好,爲什麼它會這樣做! – imukai

回答

1

ServiceLocator.Current.GetInstance<ITestOptional>();返回編譯類型ITestOptional,所以調用testUnity.HappyMethod("Cow");將由編譯器被轉換爲在接口中指定要使用的默認值。

同樣new TestingOptional();返回編譯時間TestingOptional編譯器會從類中選擇默認值。

可能的解決方法(短調整預期/不使用不同的默認值的):你可以直接使用,而不是解決interfce(有時爲測試用)統一解決型:

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

邊注:重新定義實現接口的類中的默認值不是上帝的做法 - 你會經常遇到這種令人困惑的代碼。

+0

對「良好實踐」一點的贊同 - 默認值應該正好符合這個原因(令人困惑的代碼) - 混淆是導致我首先發布的原因。我認爲如果你改變了界面的默認值,那麼它就不應該被認爲是對該界面有效 - 但這是個人觀點,在幾個層面上可能是錯誤的。 – imukai

0

您必須使用Resolve<T>方法,從IUnityContainer實例。對於樣品:

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

在你的第一個例子,你testDirectTestingOptional類型,您直接調用它HappyMethod過載的情況下,使用它指定的true默認參數值。

在你的第二個例子,你testUnityITestOptional類型的實例,並調用其HappyMethod指定的false不同的默認參數值。

這與您如何創建這些實例無關。如果你這樣做,你會觀察到相同的結果:

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

這與Unity沒有任何關係。這就是C#編譯器的工作原理。可選參數由編譯器在編譯時間填寫。在第一個示例中,您對具體類型調用HappyMethod方法,並且可選屬性標記爲true,因此C#編譯器將爲您填寫true。然而,在第二個例子中,C#編譯器不知道實現的存在,所以它會查看接口的定義。並猜測:該接口標有false