使用delegate给方法传递参数,或返回delegate对象
第一次在博客园写文章。
最近遇到一个问题,用到了多线程,以前用的时候线程启动时不需要传递参数,可现在需要时却被难了一把。。
还是先说说delegate吧
delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类。与其它的类不同,delegate类能够拥有一个签名(signature),并且它只能持有与它的签名相匹配的方法的引用。它所实现的功能与C/C++中的函数指针十分相似。它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。(摘自:gerbil )
这一段先放着吧。
那如何在线程启动时传递参数呢?
先定义一个线程启动时的执行的方法:
{
Console.WriteLine("i={0", i);
}
很简单的一个方法,显示传入int值。
启动线程的方法也很简单:
new System.Threading.Thread((System.Threading.ThreadStart)delegate { count(i); }).Start();
类似的,还可以用到Timer和ThreadPool中
ThreadPool中的应用:
System.Threading.Timer中的应用
System.Timers.Timer 中的应用
timersTimer.AutoReset = false;
timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(delegate { count(i); });
timersTimer.Enabled = true;
{
System.Timers.Timer timersTimer = new System.Timers.Timer(30000);
timersTimer.AutoReset = false;
timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(delegate { count(i); });
timersTimer.Enabled = true;
}
System.Threading.Thread.Sleep(600000);
从代码的顺序上看应该输出:
i=0
i=1
i=2
再来看看实际的输出:
i=3
i=3
i=3
出现这种问题的原因就是上面提到的,delegate指定的只是一个地址,方法的入口地址,不但如此,方法变量也是指定的一个地址,当delegate代码还未执行时,变量所指定的地址的值已经改变,所以传入给方法的值也已经改变。
解决方法也很简单:把变量i变为私有变量。
{
int j = i;//在此处添了私有变量
System.Timers.Timer timersTimer = new System.Timers.Timer(30000);
timersTimer.AutoReset = false;
timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(delegate { count(j); });
timersTimer.Enabled = true;
}
System.Threading.Thread.Sleep(600000);
再来看看输出结果:
i=0
i=1
i=2
出处:https://www.cnblogs.com/zsea/p/1209700.html
=======================================================================================
C# DynamicMethod.CreateDelegate方法代码示例
本文整理汇总了C#中System.Reflection.Emit.DynamicMethod.CreateDelegate方法的典型用法代码示例。如果您正苦于以下问题:C# DynamicMethod.CreateDelegate方法的具体用法?C# DynamicMethod.CreateDelegate怎么用?C# DynamicMethod.CreateDelegate使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类System.Reflection.Emit.DynamicMethod
的用法示例。
在下文中一共展示了DynamicMethod.CreateDelegate方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: CreateGetField
internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo)
{
DynamicMethod dynamicGet = new DynamicMethod("_", typeof(object), new Type[] { typeof(object) }, type);
ILGenerator il = dynamicGet.GetILGenerator();
if (!type.IsClass) // structs
{
var lv = il.DeclareLocal(type);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Unbox_Any, type);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloca_S, lv);
il.Emit(OpCodes.Ldfld, fieldInfo);
if (fieldInfo.FieldType.IsValueType)
il.Emit(OpCodes.Box, fieldInfo.FieldType);
}
else
{
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, fieldInfo);
if (fieldInfo.FieldType.IsValueType)
il.Emit(OpCodes.Box, fieldInfo.FieldType);
}
il.Emit(OpCodes.Ret);
return (GenericGetter)dynamicGet.CreateDelegate(typeof(GenericGetter));
}
示例2: Main
static void Main(string[] args)
{
// 2. create an instance of DynamicMethod and specify the method signature
Type returnType = typeof(Int64);
Type[] parameterTypes = new Type[] { typeof(Int32) };
DynamicMethod numberSquaredMethod =
new DynamicMethod("NumberSquared", returnType, parameterTypes);
// 3. get the ILGenerator instance
ILGenerator il = numberSquaredMethod.GetILGenerator();
//return (Int64)(x*x);
// 4. emit code using the ILGenerator
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Conv_I8);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Ret);
// 5. create a delegate to call the dynamic method
Squared numberSquared = (Squared)numberSquaredMethod.CreateDelegate(typeof(Squared));
Console.WriteLine("Result is: {0}", numberSquared(4));
}
示例3: CreateActivator
public Activator CreateActivator(Type type, out List<Type> dependencies)
{
dependencies = new List<Type>();
ConstructorInfo constructorInfo = type.GetConstructors()[0];
ParameterInfo[] parameters = constructorInfo.GetParameters();
var method = new DynamicMethod("CreateInstance", typeof(object), new[] { typeof(object[]) });
ILGenerator generator = method.GetILGenerator();
for (int index = 0; index < parameters.Length; index++)
{
Type parameterType = parameters[index].ParameterType;
dependencies.Add(parameterType);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, index);
generator.Emit(OpCodes.Ldelem_Ref);
generator.Emit(parameterType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, parameterType);
}
generator.Emit(OpCodes.Newobj, constructorInfo);
generator.Emit(OpCodes.Ret);
var activator = method.CreateDelegate(typeof(Activator)) as Activator;
return activator;
}
示例4: GetBindByName
static Action<IDbCommand, bool> GetBindByName(Type commandType)
{
if (commandType == null) return null; // GIGO
Action<IDbCommand, bool> action;
if (Link<Type, Action<IDbCommand, bool>>.TryGet(bindByNameCache, commandType, out action))
{
return action;
}
var prop = commandType.GetProperty("BindByName", BindingFlags.Public | BindingFlags.Instance);
action = null;
ParameterInfo[] indexers;
MethodInfo setter;
if (prop != null && prop.CanWrite && prop.PropertyType == typeof(bool)
&& ((indexers = prop.GetIndexParameters()) == null || indexers.Length == 0)
&& (setter = prop.GetSetMethod()) != null
)
{
var method = new DynamicMethod(commandType.Name + "_BindByName", null, new Type[] { typeof(IDbCommand), typeof(bool) });
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, commandType);
il.Emit(OpCodes.Ldarg_1);
il.EmitCall(OpCodes.Callvirt, setter, null);
il.Emit(OpCodes.Ret);
action = (Action<IDbCommand, bool>)method.CreateDelegate(typeof(Action<IDbCommand, bool>));
}
// cache it
Link<Type, Action<IDbCommand, bool>>.TryAdd(ref bindByNameCache, commandType, ref action);
return action;
}
示例5: CreateFieldGetter
public static GetValueDelegate CreateFieldGetter(FieldInfo field)
{
if (field == null)
throw new ArgumentNullException("field");
DynamicMethod dm = new DynamicMethod("FieldGetter", typeof(object),
new Type[] { typeof(object) },
field.DeclaringType, true);
ILGenerator il = dm.GetILGenerator();
if (!field.IsStatic)
{
il.Emit(OpCodes.Ldarg_0);
EmitCastToReference(il, field.DeclaringType); //to handle struct object
il.Emit(OpCodes.Ldfld, field);
}
else
il.Emit(OpCodes.Ldsfld, field);
if (field.FieldType.IsValueType)
il.Emit(OpCodes.Box, field.FieldType);
il.Emit(OpCodes.Ret);
return (GetValueDelegate)dm.CreateDelegate(typeof(GetValueDelegate));
}
示例6: GenerateDelegate
private static PropertyMapper GenerateDelegate(Type sourceType, Type targetType, bool ignoreMappings)
{
var method = new DynamicMethod("Map_" + sourceType.FullName + "_" + targetType.FullName, null, new[] { typeof(object), typeof(object) });
var il = method.GetILGenerator();
var sourceProperties = Reflector.GetAllProperties(sourceType);
var targetProperties = Reflector.GetAllProperties(targetType);
var entityMap = MappingFactory.GetEntityMap(targetType);
var matches = sourceProperties.CrossJoin(targetProperties).Where(t => t.Item2.Name == MappingFactory.GetPropertyOrColumnName(t.Item3, ignoreMappings, entityMap, false)
&& t.Item2.PropertyType == t.Item3.PropertyType
&& t.Item2.PropertyType.IsPublic
&& t.Item3.PropertyType.IsPublic
//&& (t.Item3.PropertyType.IsValueType || t.Item3.PropertyType == typeof(string))
&& t.Item2.CanRead && t.Item3.CanWrite);
foreach (var match in matches)
{
il.Emit(OpCodes.Ldarg_1);
il.EmitCastToReference(targetType);
il.Emit(OpCodes.Ldarg_0);
il.EmitCastToReference(sourceType);
il.Emit(OpCodes.Callvirt, match.Item2.GetGetMethod());
il.Emit(OpCodes.Callvirt, match.Item3.GetSetMethod());
}
il.Emit(OpCodes.Ret);
var mapper = (PropertyMapper)method.CreateDelegate(typeof(PropertyMapper));
return mapper;
}
示例7: Transcribe
public static Delegate Transcribe(Type sourceEventHandlerType, Delegate destinationEventHandler)
{
if (destinationEventHandler == null)
throw new ArgumentNullException("destinationEventHandler");
if (destinationEventHandler.GetType() == sourceEventHandlerType)
return destinationEventHandler; // already OK
var sourceArgs = VerifyStandardEventHandler(sourceEventHandlerType);
var destinationArgs = VerifyStandardEventHandler(destinationEventHandler.GetType());
var name = "_wrap" + Interlocked.Increment(ref methodIndex);
var paramTypes = new Type[sourceArgs.Length + 1];
paramTypes[0] = destinationEventHandler.GetType();
for (int i = 0; i < sourceArgs.Length; i++)
{
paramTypes[i + 1] = sourceArgs[i].ParameterType;
}
var dynamicMethod = new DynamicMethod(name, null, paramTypes);
var invoker = paramTypes[0].GetMethod("Invoke");
var ilGenerator = dynamicMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Ldarg_2);
if (!destinationArgs[1].ParameterType.IsAssignableFrom(sourceArgs[1].ParameterType))
{
ilGenerator.Emit(OpCodes.Castclass, destinationArgs[1].ParameterType);
}
ilGenerator.Emit(OpCodes.Call, invoker);
ilGenerator.Emit(OpCodes.Ret);
return dynamicMethod.CreateDelegate(sourceEventHandlerType, destinationEventHandler);
}
示例8: GetDynamicInstance
private static object GetDynamicInstance(Type type) {
if (typeof (MulticastDelegate).IsAssignableFrom(type)) {
DynamicMethod method = new DynamicMethod("XStreamDynamicDelegate", typeof (void), GetDelegateParameterTypes(type), typeof (object));
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ret);
return method.CreateDelegate(type);
}
if (type.IsSealed)
throw new ConversionException("Impossible to construct type: " + type);
// Check if we already have the type defined
string typeName = prefix + type;
lock (typeMap) {
Type dynamicType = typeMap[typeName] as Type;
if (dynamicType == null) {
TypeBuilder typeBuilder = ModuleBuilder.DefineType(typeName, TypeAttributes.Class | TypeAttributes.NotPublic, type);
ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Private, CallingConventions.Standard, new Type[0]);
cb.GetILGenerator().Emit(OpCodes.Ret);
dynamicType = typeBuilder.CreateType();
typeMap[typeName] = dynamicType;
}
return Activator.CreateInstance(dynamicType, true);
}
}
示例9: CreateDelegate
public static Delegate CreateDelegate(Delegate dlg)
{
if (dlg == null)
throw new ArgumentNullException ();
if (dlg.Target != null)
throw new ArgumentException ();
if (dlg.Method == null)
throw new ArgumentException ();
get_runtime_types ();
var ret_type = dlg.Method.ReturnType;
var param_types = dlg.Method.GetParameters ().Select (x => x.ParameterType).ToArray ();
var dynamic = new DynamicMethod (Guid.NewGuid ().ToString (), ret_type, param_types, typeof (object), true);
var ig = dynamic.GetILGenerator ();
LocalBuilder retval = null;
if (ret_type != typeof (void))
retval = ig.DeclareLocal (ret_type);
ig.Emit (OpCodes.Call, wait_for_bridge_processing_method);
var label = ig.BeginExceptionBlock ();
for (int i = 0; i < param_types.Length; i++)
ig.Emit (OpCodes.Ldarg, i);
ig.Emit (OpCodes.Call, dlg.Method);
if (retval != null)
ig.Emit (OpCodes.Stloc, retval);
ig.Emit (OpCodes.Leave, label);
bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions;
if (filter) {
ig.BeginExceptFilterBlock ();
ig.Emit (OpCodes.Call, mono_unhandled_exception_method);
ig.Emit (OpCodes.Ldc_I4_1);
ig.BeginCatchBlock (null);
} else {
ig.BeginCatchBlock (typeof (Exception));
}
ig.Emit (OpCodes.Dup);
ig.Emit (OpCodes.Call, exception_handler_method);
if (filter)
ig.Emit (OpCodes.Throw);
ig.EndExceptionBlock ();
if (retval != null)
ig.Emit (OpCodes.Ldloc, retval);
ig.Emit (OpCodes.Ret);
return dynamic.CreateDelegate (dlg.GetType ());
}
示例10: GetGetter
public static Func<object, object> GetGetter(this PropertyInfo property)
{
property.ThrowIfNull("property");
if (!property.CanRead)
{
return null;
}
var methodInfo = property.GetGetMethod(true);
if (methodInfo == null) return null;
var module = methodInfo.DeclaringType.Module;
var dynamicMethod = new DynamicMethod("", typeof(object), new Type[] { typeof(object) }, module, true);
var il = dynamicMethod.GetILGenerator();
if (!methodInfo.IsStatic)
{
il.Emit(OpCodes.Ldarg_0);
}
il.Call(methodInfo);
if (property.PropertyType.IsValueType)
{
il.Emit(OpCodes.Box, property.PropertyType);
}
il.Emit(OpCodes.Ret);
return (Func<object, object>)dynamicMethod.CreateDelegate(typeof(Func<object, object>));
}
示例11: GetFactory
public static Func<object[], object> GetFactory(this ConstructorInfo ctor)
{
ctor.ThrowIfNull("ctor");
var type = ctor.DeclaringType;
var args = ctor.GetParameters();
var module = type.Module;
var dynamicMethod = new DynamicMethod("", typeof(object), new Type[] { typeof(object[]) }, module, true);
var il = dynamicMethod.GetILGenerator();
il.CheckArgumentLength(args.Length, true);
il.LoadArguments(args, true);
il.Emit(OpCodes.Newobj, ctor);
if (type.IsValueType)
{
il.Emit(OpCodes.Box, type);
}
il.Emit(OpCodes.Ret);
return (Func<object[], object>)dynamicMethod.CreateDelegate(typeof(Func<object[], object>));
}
示例12: CreateInstance
/// <summary>
/// Create a new instance from a Type
/// </summary>
public static object CreateInstance(Type type)
{
try
{
CreateObject c = null;
if (_cacheCtor.TryGetValue(type, out c))
{
return c();
}
else
{
if (type.IsClass)
{
var dynMethod = new DynamicMethod("_", type, null);
var il = dynMethod.GetILGenerator();
il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Ret);
c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
_cacheCtor.Add(type, c);
}
else if (type.IsInterface) // some know interfaces
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>))
{
return CreateInstance(GetGenericListOfType(UnderlyingTypeOf(type)));
}
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
{
var k = type.GetGenericArguments()[0];
var v = type.GetGenericArguments()[1];
return CreateInstance(GetGenericDictionaryOfType(k, v));
}
else
{
throw LiteException.InvalidCtor(type);
}
}
else // structs
{
var dynMethod = new DynamicMethod("_", typeof(object), null);
var il = dynMethod.GetILGenerator();
var lv = il.DeclareLocal(type);
il.Emit(OpCodes.Ldloca_S, lv);
il.Emit(OpCodes.Initobj, type);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Box, type);
il.Emit(OpCodes.Ret);
c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
_cacheCtor.Add(type, c);
}
return c();
}
}
catch (Exception)
{
throw LiteException.InvalidCtor(type);
}
}
示例13: GetBindByNameSetter
private static Action<IDbCommand, bool> GetBindByNameSetter(Type commandType)
{
if (commandType == null) return null;
Action<IDbCommand, bool> action;
if (Cache.TryGetValue(commandType, out action)) return action;
var prop = commandType.GetProperty("BindByName", BindingFlags.Public | BindingFlags.Instance);
MethodInfo setter;
if (prop != null && prop.CanWrite && prop.PropertyType == typeof(bool)
&& prop.GetIndexParameters().Length == 0 && (setter = prop.GetSetMethod()) != null)
{
var methodName = GetOperationName(commandType) + "_BindByName";
var method = new DynamicMethod(methodName, null, new []{ typeof(IDbCommand), typeof(bool) });
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, commandType);
il.Emit(OpCodes.Ldarg_1);
il.EmitCall(OpCodes.Callvirt, setter, null);
il.Emit(OpCodes.Ret);
action = (Action<IDbCommand, bool>)method.CreateDelegate(typeof(Action<IDbCommand, bool>));
}
Cache.TryAdd(commandType, action);
return action;
}
示例14: GetNumberCallback
EvaluationCallback GetNumberCallback(Number number)
{
EvaluationCallback callback;
if (m_numbercallbacks.TryGetValue(number, out callback) == true) return callback;
DynamicMethod method = new DynamicMethod(String.Empty, typeof(Number), new Type[] { typeof(Object) }, typeof(TreeCompiler));
ILGenerator generator = method.GetILGenerator();
switch (number.NumberType)
{
case NumberType.Int:
generator.Emit(OpCodes.Ldc_I4, number.IntValue);
generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Int32) }));
break;
case NumberType.Float:
generator.Emit(OpCodes.Ldc_R4, number.FloatValue);
generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Single) }));
break;
default:
generator.Emit(OpCodes.Ldloc, generator.DeclareLocal(typeof(Number)).LocalIndex);
break;
}
generator.Emit(OpCodes.Ret);
callback = (EvaluationCallback)method.CreateDelegate(typeof(EvaluationCallback));
m_numbercallbacks[number] = callback;
return callback;
}
示例15: GetLightingSwipeMethod
/// <summary>
/// Generates a dynamic action that replicates vanilla functionality
/// as the types we need are private at compile time.
/// </summary>
/// <remarks>
/// An alternate would be to inject classes that replicate the nested classes in Terraria.Lighting,
/// and make the nested classes inherit ours. However, that would make me have to maintain extra code
/// </remarks>
/// <returns>Action that will process lighting swipe data</returns>
private static Action<object> GetLightingSwipeMethod()
{
var dm = new DynamicMethod("InvokeSwipe", typeof(void), new[] { typeof(object) });
var processor = dm.GetILGenerator();
//IL_0000: nop
//IL_0001: ldarg.0
//IL_0002: isinst [OTAPI]Terraria.Lighting/LightingSwipeData
//IL_0007: stloc.0
//IL_0008: ldloc.0
//IL_0009: ldfld class [mscorlib]System.Action`1<class [OTAPI]Terraria.Lighting/LightingSwipeData> [OTAPI]Terraria.Lighting/LightingSwipeData::function
//IL_000e: ldloc.0
//IL_000f: callvirt instance void class [mscorlib]System.Action`1<class [OTAPI]Terraria.Lighting/LightingSwipeData>::Invoke(!0)
//IL_0014: nop
//IL_0015: ret
var tSwipeData = typeof(global::Terraria.Lighting).GetNestedType("LightingSwipeData");
var fSwipeData = tSwipeData.GetField("function");
var swipeData = processor.DeclareLocal(tSwipeData, false);
processor.Emit(OpCodes.Ldarg_0);
processor.Emit(OpCodes.Isinst, tSwipeData);
processor.Emit(OpCodes.Stloc_0);
processor.Emit(OpCodes.Ldloc_0);
processor.Emit(OpCodes.Ldfld, fSwipeData);
processor.Emit(OpCodes.Ldloc_0);
processor.Emit(OpCodes.Callvirt, fSwipeData.FieldType.GetMethod("Invoke"));
processor.Emit(OpCodes.Ret);
return (Action<object>)dm.CreateDelegate(typeof(Action<object>));
}
注:本文中的System.Reflection.Emit.DynamicMethod.CreateDelegate方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。
出处:https://vimsky.com/examples/detail/csharp-ex-System.Reflection.Emit-DynamicMethod-CreateDelegate-method.html
=======================================================================================
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/16839029.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!