2011-04-15 49 views
25

我正在玩可選參數,看看他們如何使用接口,我遇到了一個奇怪的警告。我的設置是下面的代碼:從可選參數明確實現接口的警告

public interface ITestInterface 
{ 
    void TestOptional(int a = 5, int b = 10, object c = null); 
} 

public class TestClass : ITestInterface 
{ 

    void ITestInterface.TestOptional(int a = 5, int b = 5, object c = null) 
    { 
     Console.Write("a=" + a + " b=" + b + " c=" + c); 
    } 
} 

編譯器給了我以下警告:

  • 爲參數指定「一」不會有任何影響,因爲它適用於一個成員的默認值在不允許可選參數的上下文中使用
  • 爲參數'b'指定的默認值不起作用,因爲它適用於在不允許可選參數的上下文中使用的成員
  • 指定的默認值F或參數「C」不會有任何影響,因爲它適用於在上下文中使用的部件不允許可選參數

如果我跑這用下面的代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     ITestInterface test = new TestClass(); 
     test.TestOptional(); 
     Console.ReadLine(); 
    } 
} 

我得到我期望的「」的輸出。

我的問題是警告什麼?它指的是什麼上下文?

回答

19

C#中可選參數的問題是被調用者是否將對象看作TestClassITestInterface。在第一種情況下,該類中聲明的值適用。在第二種情況下,在界面中聲明的值適用。這是因爲編譯器使用靜態可用的類型信息來構造調用。在顯式接口實現方法永遠不會「一類」叫的情況下,總是「對接口」中10.6.1狀態

的C#語言規範:

如果可選參數出現在實現部分方法聲明(§10.2.7),顯式接口成員實現(§13.4.1)或者在單參數索引器聲明(§10.9)中,編譯器應該給出警告,因爲這些成員永遠不能在允許省略參數的方式。

+0

@GregC是的,在明確實施的情況下它們沒有任何作用。在隱式實現的情況下,重要的是在接口和類中保持相同的值。否則,您可能會遇到一些非常難以發現的錯誤。 – 2011-04-15 23:18:56

+0

他們在C++中很難發現,所以C#團隊選擇使用默認參數值等待直到最近。我想我在Eric L.的博客上看到了這一點。 – GregC 2011-04-15 23:21:36

1

克雷格,

這些警告在類方法實現指定的默認值的到來。在.net中,參數的默認值總是由參考類型決定的。當然,通過這樣的顯式接口實現,只能通過接口引用來調用這個方法 - 它定義了默認值。因此,它在課堂上的價值當然是無關緊要的,因爲它永遠不會被解決,您可以愉快地將其移除。智能感知會很好,因爲這裏的默認值永遠不會有效。

http://funcakes.posterous.com/?tag=c

http://funcakes.posterous.com/c-40-optional-parameters-default-values-and-i

+0

第二句中的術語「參考類型」有點不清楚。解釋隱式實現接口的方法定義有效地定義了兩個入口點可能會有所幫助;默認參數是可以接受的,而忽略其他參數。明確的接口定義只是定義了一個入口點,並且在那裏忽略了默認參數;它沒有定義任何默認值將被兌現的入口點。 – supercat 2013-12-19 16:17:37

-1

編譯器告訴你

void ITestInterface.TestOptional(int a = 5, int b = 5, object c = null) 

基本上是一樣的

void ITestInterface.TestOptional(int a, int b, object c) 

的原因是,因爲你必須通過調用TestOptional接口將會是s接口提供參數。班級沒有辦法讓你沒有提供參數值。

+0

我可能正在複製這些答案中的一個或多個,但我仍然要添加此答覆。沒有一個答案真的很清楚他們解釋的是什麼,我想到了,但我認爲可以用上面的代碼示例更好地解釋它。 – 2014-04-17 19:38:42