У нас есть система, в которой нам необходимо динамически изменять то, что происходит в конце набора шагов. Мы делаем это с помощью делегата. Однако методы, которые нам нужно вызвать в конце набора шагов, имеют разные подписи. У нас есть выбор на данный момент, чтобы сделать это, используя стандартную подпись делегата (возможно, копирование обработчика событий из ASP.Net) или сделать это каким-то другим способом (досрочно!) Есть ли способ сделать это с делегатами в .Net 3.5? Или мы могли бы это сделать, используя именованные параметры C# 4.0 или дополнительные параметры для делегата?Есть ли способ сделать это с делегатами в .Net 3.5?
ответ
Мы обошли это, используя подпись метода обработчика событий, то есть наш делегат ожидает (отправитель объекта, eventargs e), и мы создали собственный класс аргументов событий.
Для «нормальных» методы, вы можете пройти в открытом массиве параметров, например:
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");
...
}
Ваш вопрос довольно общий. Тем не менее, я думаю, вы могли бы использовать какой-то общий тип делегата, а затем просто переносить вызов на последний метод в простое лямбда-выражение, чтобы соответствующим образом преобразовывать параметры.
Например, предположим, что у вас есть событие, которое срабатывает с двумя строками в качестве аргумента. Это может быть создано с помощью делегата 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
в качестве обработчиков события, которое вы хотите обработать.
Я использовал эту технику, и она выразительна и кратка. –
- 1. C# (.NET 3.5) Есть ли способ получить это имя функции?
- 2. Есть ли способ сделать это?
- 3. Есть ли способ сделать это?
- 4. Есть ли способ сделать это?
- 5. Есть ли способ эмулировать UseLayoutRounding в WPF с .Net 3.5
- 6. Есть ли более элегантный способ сделать это в .NET 4.0?
- 7. Есть ли способ извлечь .NET 2.0 из .NET 3.5?
- 8. Есть ли способ сделать это в python?
- 9. Есть ли способ сделать это в Grails?
- 10. Есть ли способ сделать это в MySQL?
- 11. Есть ли способ сделать это в javascript?
- 12. Есть ли способ получить классы из System.Collections.Concurrent в .NET 3.5?
- 13. Есть ли GUID.TryParse() в .NET 3.5?
- 14. Есть ли способ сделать это на Series.map?
- 15. Есть ли способ сделать это ... R.Id. "string"?
- 16. Есть ли лучший способ сделать это (C#)?
- 17. Есть ли более рекурсивный способ сделать это?
- 18. Есть ли более быстрый способ сделать это?
- 19. Есть ли более рубиновый способ сделать это
- 20. Есть ли лучший способ сделать это?
- 21. Есть ли суровый способ сделать это?
- 22. Есть ли более эффективный способ сделать это?
- 23. Есть ли способ сделать это, css 3?
- 24. Назначение shared_ptr, есть ли способ сделать это?
- 25. Есть ли способ сделать это корпусом коммутатора?
- 26. Есть ли другой способ сделать это?
- 27. Есть ли лучший способ сделать это соединение?
- 28. Есть ли лучший способ сделать это?
- 29. Есть ли лучший способ сделать это? MySQL
- 30. Есть ли способ установить .NET 3.5 Framework без перезагрузки?
Это немного общий. Не могли бы вы дать нам еще несколько подробностей? Что вы пытаетесь выполнить с помощью вызова методов в конце шагов? Будут ли методы выводиться с этапов? Нужно ли возвращать какие-либо методы? Если вы дадите нам более подробный обзор того, что вы пытаетесь выполнить, возможно, лучший подход выйдет на свет. –