Если вы хотите работать с 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()]);
}
Для информации, другой подход, довольно распространенный в 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
, он будет использовать метод расширения.
Интересно. Придется процитировать вас здесь:
Однако в моем нынешнем реализации, метод Stop () имеет никогда не использовался и не реализовывался. В целом мои классы реализации, этот метод должен быть реализован с помощью throw NotImplementedExcetion () по умолчанию:
В этом случае у вас есть два варианта:
Обновление Я думаю, что единственный способ сделать методы необязательными - это назначить метод переменной (типа делегата, аналогичного к сигнатуре метода), а затем оценивает, является ли метод нулевым, прежде чем пытаться вызвать его где-нибудь.
Обычно это делается для обработчиков событий, в которых обработчик может присутствовать или не присутствовать, и может считаться необязательным.
Если метод не подходит для вашей реализации, бросьте InvalidOperationException
, как и большинство итераторов, когда вы вызываете для них Reset
. Альтернативой является NotSupportedException
, которое обычно используется System.IO
. Последнее более логично (поскольку оно не имеет ничего общего с текущим состоянием объекта, а только его конкретным типом), но первое, по моему опыту, чаще используется.
Однако лучше всего помещать вещи только в интерфейс. когда они вам действительно нужны - если вы все еще можете удалить Stop
, я бы сделал это на вашем месте.
Нет единой поддержки для дополнительных элементов интерфейса в языке или CLR.
Если в вашем коде нет классов, которые фактически реализуют Stop ()
, и у вас нет определенных планов сделать это в будущем, тогда он вам не нужен в вашем интерфейсе. В противном случае, если некоторые , но не все ваших объектов "останавливаются", то правильный подход действительно состоит в том, чтобы сделать его отдельным интерфейсом, например IStoppable
, и затем клиенты должны запросить его по мере необходимости.
Если ваша реализация не реализует интерфейсный метод Stop, то это явно нарушает контракт, который идет с вашим интерфейсом. Либо вы реализуете метод Stop надлежащим образом (не создавая исключение и не оставляя его пустым), либо вам нужно изменить дизайн интерфейса (чтобы изменить контракт).
С уважением
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();
}
}