Делегат С# для двух методов с разными параметрами
Я использую следующие методы:
public void M1(Int32 a)
{
// acquire MyMutex
DoSomething(a);
// release MyMutex
}
и
public void M2(String s, String t)
{
// acquire MyMutex
DoSomethingElse(s, t);
// release MyMutex
}
Из того, что я нашел до сих пор, кажется, что невозможно использовать один делегат для двух методов с разными сигнатурами.
Есть ли другие альтернативы, чтобы написать что-то вроде этого:
public void UsingMutex(...)
{
// acquire MyMutex
...
// release MyMutex
}
UsingMutex(M1);
UsingMutex(M2);
Все, что я могу представить на данный момент, - это использовать двух делегатов и логический флаг, чтобы узнать, какого делегата вызывать, но это не долгосрочное решение.
Можно комбинировать дженерики с делегатами? И если да, есть ли у вас ссылки на документацию любого типа?
Среда: С# 2.0
Ответы
Ответ 1
Абсолютно вы можете смешивать делегаты с дженериками. В 2.0, Predicate<T>
и т.д. Являются хорошими примерами этого, но вы должны иметь одинаковое количество аргументов. В этом случае, возможно, вариант заключается в использовании захватов для включения аргументов в делегат?
то есть.
public delegate void Action();
static void Main()
{
DoStuff(delegate {Foo(5);});
DoStuff(delegate {Bar("abc","def");});
}
static void DoStuff(Action action)
{
action();
}
static void Foo(int i)
{
Console.WriteLine(i);
}
static void Bar(string s, string t)
{
Console.WriteLine(s+t);
}
Обратите внимание, что Action
определен для вас в .NET 3.5, но вы можете повторно объявить его для целей 2.0; -p
Обратите внимание, что анонимный метод (delegate {...}
) также может быть параметризован:
static void Main()
{
DoStuff(delegate (string s) {Foo(5);});
DoStuff(delegate (string s) {Bar(s,"def");});
}
static void DoStuff(Action<string> action)
{
action("abc");
}
static void Foo(int i)
{
Console.WriteLine(i);
}
static void Bar(string s, string t)
{
Console.WriteLine(s+t);
}
Наконец, С# 3.0 делает это намного проще и красивее с помощью "lambdas", но это еще одна тема; -p
Ответ 2
Да, возможно комбинировать обобщения с делегатами.
public delegate void Action<T>(T x);
public delegate void Action<T,U>(T x, U y);
public void UsingMutex<T>(Action<T> x, T t) {
// acquire mutex...
x(t);
// release mutex...
}
public void UsingMutex<T,U>(Action<T,U> x, T t, U u) {
// acquire mutex...
x(t, u);
// release mutex...
}
Но вам все равно придется обрабатывать различные количества параметров, используя перегрузки.
Ответ 3
Если вы посмотрите на делегаты Func<T>
и Action<T>
в фреймворке, вы увидите, что они определяют число похожих делегатов с различным количеством параметров. Вы можете использовать generics, но это не решает количество аргументов, о которых вы говорите.