Сообщение Re[10]: Приоритет вызова перегруженных методов от 06.07.2016 11:45
Изменено 06.07.2016 13:55 Serginio1
Здравствуйте, Sinix, Вы писали:
Для Динамиков нашел решение
https://gist.github.com/jflam/777574
https://github.com/mgravell/fast-member/blob/master/FastMember/CallSiteCache.cs
На основании сделал для разного рода DynamicObject
И вызов
Для Динамиков нашел решение
https://gist.github.com/jflam/777574
https://github.com/mgravell/fast-member/blob/master/FastMember/CallSiteCache.cs
На основании сделал для разного рода DynamicObject
public class DynamicInvoker
{
public static object InvokeMember(object target, string methodName, params object[] args)
{
var targetParam = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
CSharpArgumentInfo[] parameterFlags = new CSharpArgumentInfo[args.Length + 1];
System.Linq.Expressions.Expression[] parameters = new System.Linq.Expressions.Expression[args.Length + 1];
parameterFlags[0] = targetParam;
parameters[0] = System.Linq.Expressions.Expression.Constant(target);
for (int i = 0; i < args.Length; i++)
{
parameterFlags[i + 1] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null);
parameters[i + 1] = System.Linq.Expressions.Expression.Constant(args[i]);
}
var csb = Binder.InvokeMember(CSharpBinderFlags.None, methodName, null, typeof(DynamicInvoker), parameterFlags);
var de = System.Linq.Expressions.Expression.Dynamic(csb, typeof(object), parameters);
LambdaExpression expr = System.Linq.Expressions.Expression.Lambda(de);
return expr.Compile().DynamicInvoke();
}
public static object GetValue(object target,string name)
{
CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, name, typeof(DynamicInvoker), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
return callSite.Target(callSite, target);
}
public static void SetValue(object target, string name, object value)
{
CallSite<Func<CallSite, object, object, object>> callSite = CallSite<Func<CallSite, object, object, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, name, typeof(DynamicInvoker), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) }));
callSite.Target(callSite, target, value);
}
}
И вызов
void ВывестиСвойство(object target, string ИмяСвойства)
{
textBox.AppendText(ИмяСвойства+"="+DynamicInvoker.GetValue(target, ИмяСвойства).ToString() + Environment.NewLine);
}
private void button_Click(object sender, RoutedEventArgs e)
{
dynamic res = new ExpandoObject();
res.Имя = "Тест ExpandoObject";
res.Число = 456;
res.ВСтроку = (Func<string>)(() => res.Имя);
res.Сумма = (Func<int,int,int>)((x,y) => x+y);
textBox.Clear();
textBox.AppendText("ВСтроку="+DynamicInvoker.InvokeMember(res, "ВСтроку").ToString()+Environment.NewLine);
textBox.AppendText("Сумма=" + DynamicInvoker.InvokeMember(res, "Сумма", 1, 2).ToString() + Environment.NewLine);
ВывестиСвойство(res, "Имя");
ВывестиСвойство(res, "Число");
DynamicInvoker.SetValue(res, "Имя","Новое Имя");
DynamicInvoker.SetValue(res, "Число","768");
ВывестиСвойство(res, "Имя");
ВывестиСвойство(res, "Число");
}
Re[10]: Приоритет вызова перегруженных методов
Здравствуйте, Sinix, Вы писали:
Для Динамиков нашел решение
https://gist.github.com/jflam/777574
https://github.com/mgravell/fast-member/blob/master/FastMember/CallSiteCache.cs
На основании сделал для разного рода DynamicObject
И вызов
Для Динамиков нашел решение
https://gist.github.com/jflam/777574
https://github.com/mgravell/fast-member/blob/master/FastMember/CallSiteCache.cs
На основании сделал для разного рода DynamicObject
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
using Microsoft.CSharp.RuntimeBinder;
using System.Dynamic;
using System.Runtime.CompilerServices;
namespace Тестовый
{
public class DynamicInvoker
{
public static object InvokeMember(object target, string methodName, params object[] args)
{
var targetParam = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
CSharpArgumentInfo[] parameterFlags = new CSharpArgumentInfo[args.Length + 1];
System.Linq.Expressions.Expression[] parameters = new System.Linq.Expressions.Expression[args.Length + 1];
parameterFlags[0] = targetParam;
parameters[0] = System.Linq.Expressions.Expression.Constant(target);
for (int i = 0; i < args.Length; i++)
{
parameterFlags[i + 1] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null);
parameters[i + 1] = System.Linq.Expressions.Expression.Constant(args[i]);
}
var csb = Binder.InvokeMember(CSharpBinderFlags.None, methodName, null, typeof(DynamicInvoker), parameterFlags);
var de = DynamicExpression.Dynamic(csb, typeof(object), parameters);
LambdaExpression expr = System.Linq.Expressions.Expression.Lambda(de);
return expr.Compile().DynamicInvoke();
}
public static object GetValue(object target,string name)
{
CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, name, typeof(DynamicInvoker), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
return callSite.Target(callSite, target);
}
public static void SetValue(object target, string name, object value)
{
CallSite<Func<CallSite, object, object, object>> callSite = CallSite<Func<CallSite, object, object, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, name, typeof(DynamicInvoker), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) }));
callSite.Target(callSite, target, value);
}
}
}
И вызов
void ВывестиСвойство(object target, string ИмяСвойства)
{
textBox.AppendText(ИмяСвойства+"="+DynamicInvoker.GetValue(target, ИмяСвойства).ToString() + Environment.NewLine);
}
private void button_Click(object sender, RoutedEventArgs e)
{
dynamic res = new ExpandoObject();
res.Имя = "Тест ExpandoObject";
res.Число = 456;
res.ВСтроку = (Func<string>)(() => res.Имя);
res.Сумма = (Func<int,int,int>)((x,y) => x+y);
textBox.Clear();
textBox.AppendText("ВСтроку="+DynamicInvoker.InvokeMember(res, "ВСтроку").ToString()+Environment.NewLine);
textBox.AppendText("Сумма=" + DynamicInvoker.InvokeMember(res, "Сумма", 1, 2).ToString() + Environment.NewLine);
ВывестиСвойство(res, "Имя");
ВывестиСвойство(res, "Число");
DynamicInvoker.SetValue(res, "Имя","Новое Имя");
DynamicInvoker.SetValue(res, "Число","768");
ВывестиСвойство(res, "Имя");
ВывестиСвойство(res, "Число");
}