动态对象。如何通过 TryInvoke 执行函数?
DynamicObject. How execute function through TryInvoke?
我想通过 DynamicObject 执行静态函数,但我不知道如何在不指定 class 名称 typeof(Test1)
或 typeof(Test2)
的情况下执行 saveOperation。如何更好地依赖这个?
例如
class DynObj : DynamicObject
{
GetMemberBinder saveOperation;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
saveOperation = binder;
result = this;
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
Type myType = typeof(Test1 or Test2 or ....);
result = myType.GetMethod(saveOperation.Name).Invoke(null, args);
return true;
}
}
class Program
{
static void Main(string[] args)
{
dynamic d1 = new DynObj();
d1.func1(3,6);
d1.func2(3,6);
}
}
class Test1
{
public static void func1(int a, int b){...}
}
class Test2
{
public static void func2(int a, int b){ ...}
}
第二种方式定义带有属性的静态函数(由 Carnifex 提供)
class Test3
{
[DynFuncMemberAttribute]
public static void func3(int a, int b){...}
}
并获取类型
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
Type myType = null;
foreach (Type types in Assembly.GetExecutingAssembly().GetTypes())
{
foreach (MethodInfo mi in types.GetMethods())
{
foreach (CustomAttributeData cad in mi.CustomAttributes)
{
if (cad.AttributeType == typeof(DynFuncMemberAttribute))
{
myType = types;
break;
}
}
}
}
result = (myType != null)? myType.GetMethod(saveOperation.Name).Invoke(null, args): null;
return myType != null;
}
您可以使用一些属性并设置例如。 [DynFuncMemberAttribute] 到 class 或其自身的方法。
然后在 TryInvoke(或构造函数)中获取所有标有此属性的 types/methods,构建一些 map/cache 瞧 :)
编辑:这是使用此属性的示例。请记住,如果找到两个具有相同名称的方法,BuildCache() 将抛出异常。
[AttributeUsage(AttributeTargets.Method)]
class DynFuncMemberAttribute : Attribute
{
}
class DynObj : DynamicObject
{
Dictionary<string, MethodInfo> cache;
GetMemberBinder saveOperation;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
saveOperation = binder;
result = this;
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
if (cache == null)
cache = BuildCache();
MethodInfo mi;
if (cache.TryGetValue(saveOperation.Name, out mi))
{
result = mi.Invoke(null, args);
return true;
}
result = null;
return false;
}
private Dictionary<string, MethodInfo> BuildCache()
{
return Assembly.GetEntryAssembly()
.GetTypes()
.SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.Static))
.Where(mi => mi.GetCustomAttribute<DynFuncMemberAttribute>() != null)
.ToDictionary(mi => mi.Name);
}
}
class Program
{
static void Main(string[] args)
{
dynamic d1 = new DynObj();
d1.func1(3, 6);
d1.func2(3, 6);
}
}
class Test1
{
[DynFuncMember]
public static void func1(int a, int b)
{
Console.WriteLine("func1");
}
}
class Test2
{
[DynFuncMember]
public static void func2(int a, int b)
{
Console.WriteLine("func2");
}
}
我想通过 DynamicObject 执行静态函数,但我不知道如何在不指定 class 名称 typeof(Test1)
或 typeof(Test2)
的情况下执行 saveOperation。如何更好地依赖这个?
例如
class DynObj : DynamicObject
{
GetMemberBinder saveOperation;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
saveOperation = binder;
result = this;
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
Type myType = typeof(Test1 or Test2 or ....);
result = myType.GetMethod(saveOperation.Name).Invoke(null, args);
return true;
}
}
class Program
{
static void Main(string[] args)
{
dynamic d1 = new DynObj();
d1.func1(3,6);
d1.func2(3,6);
}
}
class Test1
{
public static void func1(int a, int b){...}
}
class Test2
{
public static void func2(int a, int b){ ...}
}
第二种方式定义带有属性的静态函数(由 Carnifex 提供)
class Test3
{
[DynFuncMemberAttribute]
public static void func3(int a, int b){...}
}
并获取类型
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
Type myType = null;
foreach (Type types in Assembly.GetExecutingAssembly().GetTypes())
{
foreach (MethodInfo mi in types.GetMethods())
{
foreach (CustomAttributeData cad in mi.CustomAttributes)
{
if (cad.AttributeType == typeof(DynFuncMemberAttribute))
{
myType = types;
break;
}
}
}
}
result = (myType != null)? myType.GetMethod(saveOperation.Name).Invoke(null, args): null;
return myType != null;
}
您可以使用一些属性并设置例如。 [DynFuncMemberAttribute] 到 class 或其自身的方法。
然后在 TryInvoke(或构造函数)中获取所有标有此属性的 types/methods,构建一些 map/cache 瞧 :)
编辑:这是使用此属性的示例。请记住,如果找到两个具有相同名称的方法,BuildCache() 将抛出异常。
[AttributeUsage(AttributeTargets.Method)]
class DynFuncMemberAttribute : Attribute
{
}
class DynObj : DynamicObject
{
Dictionary<string, MethodInfo> cache;
GetMemberBinder saveOperation;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
saveOperation = binder;
result = this;
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
if (cache == null)
cache = BuildCache();
MethodInfo mi;
if (cache.TryGetValue(saveOperation.Name, out mi))
{
result = mi.Invoke(null, args);
return true;
}
result = null;
return false;
}
private Dictionary<string, MethodInfo> BuildCache()
{
return Assembly.GetEntryAssembly()
.GetTypes()
.SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.Static))
.Where(mi => mi.GetCustomAttribute<DynFuncMemberAttribute>() != null)
.ToDictionary(mi => mi.Name);
}
}
class Program
{
static void Main(string[] args)
{
dynamic d1 = new DynObj();
d1.func1(3, 6);
d1.func2(3, 6);
}
}
class Test1
{
[DynFuncMember]
public static void func1(int a, int b)
{
Console.WriteLine("func1");
}
}
class Test2
{
[DynFuncMember]
public static void func2(int a, int b)
{
Console.WriteLine("func2");
}
}