С# Интерфейсы с дополнительными методами
Я понимаю, что интерфейсы - это контракты, и любые изменения (даже дополнения) нарушают любой зависимый код. Тем не менее, я мог бы поклясться, что кое-что прочитал, что одна из последних версий .NET(3, 3.5) добавила новый атрибут, который может быть применен к новым членам интерфейса. Этот атрибут разрешал управление версиями и/или создание элементов необязательно. Это было бы что-то вроде:
interface ITest
{
void MethodOne();
[InterfaceVersion(2)]
void MethodTwo();
}
Я смотрел высоко и низко для этого, но просто не мог найти его. Мне интересно, я просто неправильно понял все, что, как я думаю, читал, и нет такой вещи. У кого-то есть понимание?
Ответы
Ответ 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
необязательной.
Ответ 8
Возможно, вы думаете о частичных методах (MSDN).