Как создать интерфейс метода с переменными параметрами/сигнатурами разных методов?

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

например.

public interface IViewModel
{
    //...
    void ResetReferences(); 
}

// and then, in my class implementations, something like this:
public class LocationViewModel : IViewModel
{
    public void ResetReferences(List<StateProvinces> stateProvinces) //...
}

public class ProductViewModel : IViewModel
{
    public void ResetReferences(List<Color> colors, List<Size> sizes) //...
}

Поэтому обратите внимание, что я хочу стандартизировать соглашение об именах "RestReferences". Я уверен, что не могу этого сделать, но есть ли шаблон дизайна, который мог бы работать? например в моем интерфейсе, что-то вроде ниже?

// variable parameters
void ResetReferences(params object[] list); 

Но как я могу заставить проверять тип или вызвать фактическую подпись метода, которую я хочу, и т.д.

Может быть, интерфейс неправильный? Может быть, просто базовый класс и некоторые условные обозначения?

Спасибо,

Ответы

Ответ 1

Замените ваши списки args объектами, которые реализуют связанный интерфейс:

public interface IViewModel
{
    //...
    void ResetReferences(IResetValues vals); 
}

Я должен добавить, что IMO, "ResetReferences()" не должен принимать аргумент... он должен reset для некоторого значения по умолчанию, которое будет специфично для отдельных типов (типов), которые реализуют ваш интерфейс... "Reset" - это слово, которое для меня означает "восстановить исходное состояние"... добавление args подразумевает, что вы можете контролировать это.

Ответ 2

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

Если я не полностью пойму, что вы пытаетесь сделать, вы не по пути.

Ответ 3

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

Один из вариантов - инкапсулировать параметры в другой тип и сделать класс общим для этого типа. Например:

public interface IViewModel<T>
{
    void ResetReferences(T data);
}

Затем вы инкапсулируете List<Color> colors, List<Size> sizes в один тип и, возможно, поместите List<StateProvinces> stateProvinces в другой.

Это несколько неудобно, хотя...

Ответ 4

Вам нужно будет реализовать метод интерфейса, но вы все равно можете сделать то, что хотите

public class LocationViewModel : IViewModel
{
    public void ResetReferences(List<StateProvinces> stateProvinces) // ...

    void IViewModel.ResetReferences() // ...
}

Ответ 5

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

Определение интерфейса - это целая подпись.

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