Определить дополнительные методы внедрения в Интерфейсе?

Если вы хотите работать с ArrayLists в решении, вы можете попробовать это:

public final String [] f(final String [] first, final String [] second) {
    // Assuming non-null for brevity.
    final ArrayList<String> resultList = new ArrayList<String>(Arrays.asList(first));
    resultList.addAll(new ArrayList<String>(Arrays.asList(second)));
    return resultList.toArray(new String [resultList.size()]);
}
8
задан David.Chu.ca 24 July 2009 в 05:17
поделиться

6 ответов

Для информации, другой подход, довольно распространенный в BCL, - Поддерживает * на том же интерфейсе, то есть

bool SupportsStop {get;}
void Stop();

(примеры этого, например, в IBindingList ).

Я не претендую на то, что он «чистый» или что-то в этом роде, но это работает - но это означает, что теперь у вас есть два метода для реализации для каждой функции, а не один. Отдельные интерфейсы (например, IStoppableReader ) могут быть предпочтительнее.

Для информации: если реализация является общей для всех реализаций, то вы можете использовать методы расширения; для тривиального примера:

public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) {
    foreach(T item in items) list.Add(item);
}

(или эквивалент для вашего интерфейса). Если вы предоставите более специализированную версию для конкретного типа, тогда он будет иметь приоритет (но только если вызывающий знает о переменной как конкретный тип, а не интерфейс). Таким образом, с учетом вышеизложенного, любой, кто сознательно использует List , по-прежнему использует версию AddRange List ; но если у него есть List , но он известен только как IList , он будет использовать метод расширения.

6
ответ дан 5 December 2019 в 07:36
поделиться

Интересно. Придется процитировать вас здесь:

Однако в моем нынешнем реализации, метод Stop () имеет никогда не использовался и не реализовывался. В целом мои классы реализации, этот метод должен быть реализован с помощью throw NotImplementedExcetion () по умолчанию:

В этом случае у вас есть два варианта:

  1. Удалить метод Stop () из интерфейса. Если он не используется всеми разработчиками интерфейса, он явно не принадлежит ему .
    • Вместо интерфейса преобразуйте свой интерфейс в абстрактный базовый класс. Таким образом, нет необходимости переопределять пустой метод Stop () до тех пор, пока вам это не понадобится.

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

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

7
ответ дан 5 December 2019 в 07:36
поделиться

Если метод не подходит для вашей реализации, бросьте InvalidOperationException , как и большинство итераторов, когда вы вызываете для них Reset . Альтернативой является NotSupportedException , которое обычно используется System.IO . Последнее более логично (поскольку оно не имеет ничего общего с текущим состоянием объекта, а только его конкретным типом), но первое, по моему опыту, чаще используется.

Однако лучше всего помещать вещи только в интерфейс. когда они вам действительно нужны - если вы все еще можете удалить Stop , я бы сделал это на вашем месте.

Нет единой поддержки для дополнительных элементов интерфейса в языке или CLR.

5
ответ дан 5 December 2019 в 07:36
поделиться

Если в вашем коде нет классов, которые фактически реализуют Stop () , и у вас нет определенных планов сделать это в будущем, тогда он вам не нужен в вашем интерфейсе. В противном случае, если некоторые , но не все ваших объектов "останавливаются", то правильный подход действительно состоит в том, чтобы сделать его отдельным интерфейсом, например IStoppable , и затем клиенты должны запросить его по мере необходимости.

4
ответ дан 5 December 2019 в 07:36
поделиться

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

С уважением

0
ответ дан 5 December 2019 в 07:36
поделиться

C # версии 4 ( или vNext ) рассматривает реализацию по умолчанию для интерфейсов - я слышал, что на channel9 несколько месяцев тому назад ;).

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

До тех пор вы можете обойтись без методов расширения ...

Или ваш тип может использовать делегаты.

interface IOptionalStop
{
    Action Stop { get; }
}

public class WithStop : IOptionalStop
{
    #region IOptionalStop Members

    public Action Stop
    {
        get;
        private set;
    }

    #endregion

    public WithStop()
    {
        this.Stop =
            delegate
            {
                // we are going to stop, honest!
            };
    }
}

public class WithoutStop : IOptionalStop
{
    #region IOptionalStop Members

    public Action Stop
    {
        get;
        private set;
    }

    #endregion
}


public class Program
{
    public static string Text { get; set; }


    public static void Main(string[] args)
    {
        var a = new WithStop();

        a.Stop();

        var o = new WithoutStop();

        // Stop is null and we cannot actually call it
        a.Stop();

    }
}
0
ответ дан 5 December 2019 в 07:36
поделиться
Другие вопросы по тегам:

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