#c# #.net #reflection
#c# #.net #отражение
Вопрос:
Я хочу создавать различные типы делегатов только с одним общим методом, подобным этому.
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");
Значение Boo args.Length
должно быть равно 1 и ret
равно null
.
Возможно ли это в C #?
- Нет
dynamic
generic
илиlinq.exprssion
sry.
Обновить
Это должно быть сделано с Reflection
помощью . Приведенные выше 3 делегата являются лишь примером. Тип делегатов будет определен во время выполнения.
Ответ №1:
Сначала вы можете определить делегат для вашего общего метода:
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();
}
Преимущество этого подхода заключается в том, что вы можете сделать свои методы расширения более полными и проверять ошибки, а Также давать отзывы и т. Д. И т. Д
Комментарии:
1. Блестяще! 🙂 🙂
Ответ №2:
Можете ли вы просто сделать:
Action action = () => Boo();
Func<int> action2 = () => (int)Boo();
Func<string, string> action3 = x => (string)Boo(x);
Если нет, то почему бы и нет?
Ответ №3:
Наконец-то покончено с этим способом https://github.com/pjc0247/SlowSharp/blob/master/Slowsharp/Runner/Runner .Lambda.cs
Я думаю, что это не может быть сокращено без Linq.Выражение.