Интерфейсы C# с дополнительными методами

Я понимаю, что интерфейсы являются контрактами, и любые изменения (даже дополнения) взламывают любой зависимый код. Однако я, возможно, поклялся, что считал что-то некоторое время назад что одна из недавних версий.NET (3, 3.5??) добавил новый атрибут, который мог быть применен к новым интерфейсным участникам. Этот атрибут позволил дополнительным участникам управления версиями и/или создания. Это было бы что-то как:

interface ITest
{
    void MethodOne();

    [InterfaceVersion(2)]
    void MethodTwo();
}

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

39
задан Nelson Rothermel 4 March 2010 в 13:26
поделиться

7 ответов

Вы должны создать два интерфейса:

interface ITest
{
    void MethodOne();
}

interface ITest2 : ITest
{
    void MethodTwo();
}

Это также позволит понять, какая функциональность требует какой версии ваших интерфейсов, так что вам не придется проверять, реализует ли класс, реализующий интерфейс, только один или оба метода.

47
ответ дан 27 November 2019 в 02:31
поделиться

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

    interface IFoo {
            int RowCount();
    }

    static class _FooExtensions {
            public static bool HasAnyRows (this IFoo foo) {
                    return foo.RowCount() > 0;
            }
    }

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

2
ответ дан 27 November 2019 в 02:31
поделиться

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

public abstract class Test
{
     public abstract void MethodOne();
     public virtual void MethodTwo() { }
}

Это позволит пользователю решить, хотят ли они переопределить MethodTwo при наследовании от Test, при этом принудительно переопределив MethodOne.

5
ответ дан 27 November 2019 в 02:31
поделиться

Возможно, вы читали что-то вроде

 interface ITest
{
    void MethodOne();

    [InterfaceVersion(2)]
    void MethodTwo();
}



[AttributeUsage(AttributeTargets.All)]
public class InterfaceVersion : System.Attribute
{
    public readonly int N;

    public InterfaceVersion(int n) 
    {
        this.N = n;
    }
}

, но я не думаю, что это может сделать реализацию MethodTwo необязательной.

РЕДАКТИРОВАТЬ:

Я только что обнаружил, запустив код, что он действительно не делает реализацию MethodTwo необязательной.

1
ответ дан 27 November 2019 в 02:31
поделиться

Я не видел такого атрибута, но думаю, это возможно. В этой статье в MSDN описывается управление версиями с помощью ключевых слов overrides и new .

Короче говоря, C # снабжен языковыми функциями, которые позволяют производным классам развиваться и при этом поддерживать совместимость. В этом примере показано чисто отношение между базой и производным, но на самом деле база будет реализовывать интерфейс, который вам нужен для версии. Наличие одного интерфейса, требующего другого (предыдущей версии) интерфейса в сочетании с этим методом, также весьма полезно.

Пример создания интерфейса, для которого требуется другой:

public interface IMyInterface
{
  void FirstMethod();
}

public interface IMySecondInterface : IMyInterface
{
  void SecondMethod();
}

Пример использования наследования для поддержания совместимости:

public class MyBase 
{
   public virtual string Meth1() 
   {
      return "MyBase-Meth1";
   }
   public virtual string Meth2() 
   {
      return "MyBase-Meth2";
   }
   public virtual string Meth3() 
   {
      return "MyBase-Meth3";
   }
}

class MyDerived : MyBase 
{
   // Overrides the virtual method Meth1 using the override keyword:
   public override string Meth1() 
   {
      return "MyDerived-Meth1";
   }
   // Explicitly hide the virtual method Meth2 using the new
   // keyword:
   public new string Meth2() 
   {
      return "MyDerived-Meth2";
   }
   // Because no keyword is specified in the following declaration
   // a warning will be issued to alert the programmer that 
   // the method hides the inherited member MyBase.Meth3():
   public string Meth3() 
   {
      return "MyDerived-Meth3";
   }

   public static void Main() 
   {
      MyDerived mD = new MyDerived();
      MyBase mB = (MyBase) mD;

      System.Console.WriteLine(mB.Meth1());
      System.Console.WriteLine(mB.Meth2());
      System.Console.WriteLine(mB.Meth3());
   }
}
10
ответ дан 27 November 2019 в 02:31
поделиться

В платформе .NET такого атрибута нет.

5
ответ дан 27 November 2019 в 02:31
поделиться

Возможно, вы думаете о новой функции "no pia" в C # 4? То есть мы позволяем вам «связывать» только те части интерфейса, которые вы фактически используете из PIA, а затем вы можете пропустить отправку PIA своим клиентам. Если вы затем сделаете это несколько раз в нескольких разных сборках, CLR выполнит работу по выяснению того, что все эти связанные частичные интерфейсы логически одного типа, и объединит их. Таким образом, вы можете передавать объекты, реализующие каждую разновидность интерфейса, из одной сборки в другую, и все это просто работает.Однако исходные интерфейсы , из которых создаются интерфейсы «no pia», должны быть одинаковыми.

6
ответ дан 27 November 2019 в 02:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: