Как передать список делегатов в качестве параметра («довольно») - PullRequest
0 голосов
/ 26 апреля 2020

У меня слишком большой конструктор (12 параметров). Все эти параметры являются либо Действиями (Action, Action), либо обобщенными c делегатами (которых у меня около 8).

Как я могу передать список делегатов и, следовательно, уменьшить количество параметров мой конструктор таким образом, что все еще читается? Я хотел бы добиться чего-то вроде этого:

// Controller //
var methods = new List<StrategyDelegate>()
{
    model.OpenWindowMethod,
    model.CloseWindowMethod
};
View(methods);

// View //
public delegate void StrategyDelegate();
private StrategyDelegate _openWindow;
private StrategyDelegate _closeWindow;

View(List<StrategyDelegate> methodsToCall)
{
    _openWindow = methodsToCall.Find("model.OpenWindowMethod"); ???
    _closeWindow = methodsToCall[1]; ???
}

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

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020

Передача большого количества делегатов в качестве аргументов конструктора не является лучшей практикой. Передача их как List<delegate> может быть еще хуже для меня. Это приносит некоторые дополнительные риски с этим. Но это не должно быть проблемой.

Что если вы попытаетесь передать класс в качестве параметра:

public class MyActions
{
    public StrategyDelegate OpenWindow { get; set; }
    public StrategyDelegate CloseWindow { get; set; }
}

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


Я думаю, что go для наследования, если делегаты не будут не изменяется во время работы:

Я бы создал абстрактный класс:

public abstract class MyBaseClass
{
    public abstract void OpenWindow();
    public abstract void CloseWindow();  // <-- at least pass a object sender?
}

public class MyClass : MyBaseClass
{
    public override void OpenWindow()
    { 
        // you code:
    }

    public override void CloseWindow()
    {
        // you code:
    }
}

public class ViewConfiguration 
{
    public MyBaseClass _myBaseClass;

    public ViewConfiguration(MyBaseClass myBaseClass)
    {
        _myBaseClass = myBaseClass;
    }


    public void CloseWindow()
    {
        _myBaseClass?.CloseWindow();
    }
}
0 голосов
/ 26 апреля 2020

Создайте новый класс, который имеет целый набор методов для различных делегатов, которые вы хотите передать в View из контроллера; простой пример с примитивными типами:

public class ViewConfiguration {
    public int a;
    public int b;
    public string c;
    public bool d;

    public ViewConfiguration setA(int newA) {
        // setB, setC, and setD will follow a similar structure
        a = newA;
        return this;
    }
}

Затем контроллер может создать конфигурацию следующим образом:

var config = new ViewConfiguration();
// you can do any combination/order of these
config.setA(2).setB(4).setC("hello").setD(true);

Затем вы можете передать config в View, а View может просто сделать config.a. Возможно, вам следует сделать так, чтобы только 1010 * был опубликован со свойствами (скрывайте непосредственно поля установки за установленными методами), но это общая идея.

...