Подтвердить что ты не робот

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

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

interface ITest
{
    void MethodOne();

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

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

4b9b3361

Ответ 1

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

interface ITest
{
    void MethodOne();
}

interface ITest2 : ITest
{
    void MethodTwo();
}

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

В .NET Framework нет такого атрибута.

Ответ 5

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

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

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

Ответ 6

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

    interface IFoo {
            int RowCount();
    }

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

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

Ответ 7

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

 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 опциональной.

EDIT:

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