CreateDelegate, используя один общий метод - PullRequest
0 голосов
/ 12 апреля 2019

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

public static object Boo(params object[] args) {
    return null;
}
MethodInfo boo = /* MethodInfo of Boo */

// Boo's arg.Length should be `0`
Action action = (Action)Delegate.CreateDelegate(typeof(Action), null, boo);

Func<int> action2 = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), null, boo);
Func<string, string> action3 = (Func<string, string>)Delegate.CreateDelegate(typeof(Func<string, string>), null, boo);

Итак, если вы вызываете action3 так же, как это

var ret = action3.Invoke("booo");

Бу args.Length должно быть 1, а ret равно null.

Возможно ли это в C #?

  • Нет dynamic, generic или linq.exprssion sry.

Обновление

Это должно быть сделано с Reflection. Выше 3 делегата являются лишь примером. Тип делегатов будет определен во время выполнения.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2019

Вы можете сначала определить делегата для вашего общего метода:

public delegate object BooDelegate(params object[] args);

Вы можете использовать методы расширения следующим образом:

public static class DelegatesProviderExtensions
{
    public static Func<int> GetFuncOfInt(this BooDelegate booDelegate) => () => (int) booDelegate();

    public static Action GetAction(this BooDelegate booDelegate) => () => booDelegate();

    public static Func<string, string> GetFuncOfStringString(this BooDelegate booDelegate) =>
        s => booDelegate(s) as string;
}

И проверить:

private static void Main(string[] args)
{
    BooDelegate boo1 = objects => 1;
    BooDelegate boo2 = objects =>
    {
        Console.WriteLine("Boo!");
        return null;
    };
    BooDelegate boo3 = objects => $"{objects[0]} World";

    Console.WriteLine(boo1.GetFuncOfInt()());
    boo2.GetAction()();
    Console.WriteLine(boo3.GetFuncOfStringString()("Hello"));
    Console.ReadLine();
}

Преимущество этого подхода состоит в том, что вы можете сделать ваши методы расширения более полными и проверять ошибки, а также предоставлять обратную связь и т. Д. И т. Д.

2 голосов
/ 12 апреля 2019

Можете ли вы просто сделать:

Action action = () => Boo();
Func<int> action2 = () => (int)Boo();
Func<string, string> action3 = x => (string)Boo(x);

Если нет, то почему?

0 голосов
/ 13 апреля 2019

Наконец сделано таким образом https://github.com/pjc0247/SlowSharp/blob/master/Slowsharp/Runner/Runner.Lambda.cs

Я думаю, что это невозможно сократить без Linq.Expression.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...