Есть ли способ сделать это с делегатами в .Net 3.5? - PullRequest
0 голосов
/ 21 мая 2010

У нас есть система, в которой нам нужно динамически изменять то, что происходит в конце набора шагов.Мы делаем это с помощью делегата.Однако методы, которые нам нужно вызывать в конце набора шагов, имеют разные подписи.На данный момент у нас есть выбор: сделать это с помощью стандартной подписи делегата (возможно, копируя обработчик события из ASP.Net) или сделать это другим способом (недооценено!). Есть ли способ сделать это с делегатами в .Net3,5?Или мы могли бы сделать это, используя именованные параметры C # 4.0 или дополнительные параметры делегата?

Ответы [ 3 ]

2 голосов
/ 21 мая 2010

Ваш вопрос довольно общий. Тем не менее, я думаю, что вы можете использовать некоторый общий тип делегата, а затем просто обернуть вызов метода final в простое лямбда-выражение, чтобы соответствующим образом преобразовать параметры.

Например, допустим, у вас есть событие, которое запускается с двумя строками в качестве аргумента. Это может быть создано с помощью делегата Action<string, string> из .NET 3.5. Тогда у вас будет два метода, которые вы хотите вызвать (и вам нужно будет выбирать между ними динамически):

void Foo(int n, string s) { /* expects int as the first parameter */ } 
void Bar(string concatenated) { /* expects concatenated string */ }

Затем вы можете создать двух делегатов действий, таких как:

// Converts parameter to int and calls 'Foo'
Action<string, string> callFoo = (s1, s2) => Foo(Int32.Parse(s1), s2);
// Concatenates parameters and calls 'Bar'
Action<string, string> callBar = (s1, s2) => Bar(s1 + ", " + s2);

Код в лямбда-выражениях служит простым адаптером, который преобразует фактические параметры в параметры, ожидаемые методом. Теперь вы можете динамически добавлять / удалять callFoo и callBar в качестве обработчиков события, которое вы хотите обработать.

0 голосов
/ 26 мая 2010

Мы обошли это, используя сигнатуру метода обработчика событий, т.е. наш делегат ожидает (отправитель объекта, eventargs e), и мы создали собственный класс args события.

0 голосов
/ 21 мая 2010

Для «обычных» методов вы можете передать открытый массив параметров, например:

public void Test(params string[] string parameters);

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

Вы можете создавать «объекты состояния», которые содержат разные свойства с параметрами для каждого вызванного метода, и метод будет принимать только один параметр.

public class StateObject1
{
    public string parameter1;
    public int parameter2;
}

public class StateObject2
{
    public DateTime parameter1;
    public DateTime parameter2;
}

public void Handler1(object stateObject)
{
    if (!(stateObject is StateObject1))
        throw new ArgumentException("Invalid state object type");
    ...
}

public void Handler2(object stateObject)
{
    if (!(stateObject is StateObject2))
        throw new ArgumentException("Invalid state object type");
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...