Предупреждение от явной реализации интерфейса с дополнительными параметрами - PullRequest
30 голосов
/ 16 апреля 2011

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

 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);
     }
 }

Компилятор выдает мне следующие предупреждения:

  • Значение по умолчанию, указанное для параметра 'a', не будет иметь никакого эффекта, потому что оноприменяется к элементу, который используется в контекстах, которые не допускают необязательные аргументы
  • Значение по умолчанию, указанное для параметра 'b', не будет иметь никакого эффекта, поскольку оно применяется к элементу, который используется в контекстах, которые не допускают необязательныеАргументы
  • Значение по умолчанию, указанное для параметра 'c', не будет иметь никакого эффекта, поскольку оно применяется к элементу, который используется в контекстах, которые не допускают необязательные аргументы

Если я запускаю этосо следующим кодом:

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

Я получаю вывод "a=5 b=10 c=", как я и ожидал.

Мой вопрос: для чего нужно предупреждение?На какие контексты он ссылается?

Ответы [ 4 ]

23 голосов
/ 16 апреля 2011

Проблема с необязательными аргументами в C # заключается в том, видит ли вызываемый объект объект как TestClass или ITestInterface. В первом случае применяются значения, объявленные в классе. Во втором случае применяются значения, объявленные в интерфейсе. Это связано с тем, что компилятор использует статически доступную информацию о типах для построения вызова. В случае явной реализации интерфейса метод никогда не вызывается «для класса», всегда «для интерфейса»

Спецификация языка C # в 10.6.1 состояниях:

Если необязательные параметры встречаются в реализации частичного объявления метода (§10.2.7), явной реализации элемента интерфейса (§13.4.1) или в объявлении индексатора с одним параметром (§10.9), компилятор должен выдать предупреждение, поскольку эти члены никогда не могут быть вызваны способом, который позволяет опускать аргументы.

4 голосов
/ 17 апреля 2014

Компилятор говорит вам

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

В основном совпадает с

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

Причина в том, что вы должны вызывать TestOptional через интерфейс, интерфейс будет предоставлять параметры. В классе невозможно, чтобы вам не было предоставлено значение параметра.

4 голосов
/ 16 апреля 2011
1 голос
/ 16 апреля 2011

Craig,

Эти предупреждения исходят из значений по умолчанию, указанных в реализации метода класса.В .net значение по умолчанию для аргумента всегда определяется ссылочным типом.И, конечно же, в явной реализации интерфейса, подобной этой, этот метод можно вызвать только через ссылку на интерфейс, которая определяет значение по умолчанию.Таким образом, это, конечно, не имеет значения, какую ценность вы ставите здесь, в классе, так как она никогда не будет решена, и вы можете удалить ее счастливо.Intellisense будет в порядке, учитывая, что значение по умолчанию здесь никогда не может быть эффективным.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...