2010-05-21 2 views
0

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

+2

Это немного общий. Не могли бы вы дать нам еще несколько подробностей? Что вы пытаетесь выполнить с помощью вызова методов в конце шагов? Будут ли методы выводиться с этапов? Нужно ли возвращать какие-либо методы? Если вы дадите нам более подробный обзор того, что вы пытаетесь выполнить, возможно, лучший подход выйдет на свет. –

ответ

0

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

0

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

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"); 
    ... 
} 
2

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

Например, предположим, что у вас есть событие, которое срабатывает с двумя строками в качестве аргумента. Это может быть создано с помощью делегата 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

Я использовал эту технику, и она выразительна и кратка. –

Смежные вопросы