Co jest naprawdę dziwne jest to, że wartość można umieścić za pomocą opcjonalnego parametru w interfejsie faktycznie robi różnicę. Przypuszczam, że musisz zapytać, czy wartość jest szczegółem interfejsu, czy szczegółem implementacji. Powiedziałbym to drugie, ale rzeczy zachowują się jak poprzednie. Poniższy kod wyprowadza na przykład 1 0 2 5 3 7.
// Output:
// 1 0
// 2 5
// 3 7
namespace ScrapCSConsole
{
using System;
interface IMyTest
{
void MyTestMethod(int notOptional, int optional = 5);
}
interface IMyOtherTest
{
void MyTestMethod(int notOptional, int optional = 7);
}
class MyTest : IMyTest, IMyOtherTest
{
public void MyTestMethod(int notOptional, int optional = 0)
{
Console.WriteLine(string.Format("{0} {1}", notOptional, optional));
}
}
class Program
{
static void Main(string[] args)
{
MyTest myTest1 = new MyTest();
myTest1.MyTestMethod(1);
IMyTest myTest2 = myTest1;
myTest2.MyTestMethod(2);
IMyOtherTest myTest3 = myTest1;
myTest3.MyTestMethod(3);
}
}
}
Jaki jest rodzaj interesujące jest to, że jeśli interfejs sprawia, że parametr opcjonalny klasy wykonawczych nie musi zrobić to samo:
// Optput:
// 2 5
namespace ScrapCSConsole
{
using System;
interface IMyTest
{
void MyTestMethod(int notOptional, int optional = 5);
}
class MyTest : IMyTest
{
public void MyTestMethod(int notOptional, int optional)
{
Console.WriteLine(string.Format("{0} {1}", notOptional, optional));
}
}
class Program
{
static void Main(string[] args)
{
MyTest myTest1 = new MyTest();
// The following line won't compile as it does not pass a required
// parameter.
//myTest1.MyTestMethod(1);
IMyTest myTest2 = myTest1;
myTest2.MyTestMethod(2);
}
}
}
Co wydaje się być błędem jest jednak, że jeśli Interfejs jest jawnie implementowany, wartość podana w klasie dla wartości opcjonalnej jest bezcelowa. Jak w poniższym przykładzie można użyć wartości 9? To nawet nie daje ostrzeżenia podczas kompilacji.
// Optput:
// 2 5
namespace ScrapCSConsole
{
using System;
interface IMyTest
{
void MyTestMethod(int notOptional, int optional = 5);
}
class MyTest : IMyTest
{
void IMyTest.MyTestMethod(int notOptional, int optional = 9)
{
Console.WriteLine(string.Format("{0} {1}", notOptional, optional));
}
}
class Program
{
static void Main(string[] args)
{
MyTest myTest1 = new MyTest();
// The following line won't compile as MyTest method is not available
// without first casting to IMyTest
//myTest1.MyTestMethod(1);
IMyTest myTest2 = new MyTest();
myTest2.MyTestMethod(2);
}
}
}
Poniższe komentarze Martina zawierają szczegółowy przykład różnych pułapek i chciałbym, aby kompilator oznaczał niezgodne domyślne argumenty. To powiedziawszy, używam tego w moim kodzie, ponieważ wskazuje on mój zamiar jako programisty zarówno na poziomie interfejsu, jak i na poziomie implementacji, aby inni programiści mogli to zobaczyć. –
Interesujące pytania pokrewne: "[Czy jest jakikolwiek powód deklarowania opcjonalnych parametrów w interfejsie?] (Https: // stackoverflow.com/questions/6752762 /) "i" [Dlaczego parametry opcjonalne C# 4 zdefiniowane w interfejsie nie są wymuszane w klasie implementacji?] (https://stackoverflow.com/questions/4922714/) ", drugie z interesującym [odpowiedź od Lipperta] (https://stackoverflow.com/a/4923642/1028230). – ruffin