我想學習使用c#的動態方法及其實例。
動態方法和Reflection之間是否有任何關係?
請幫幫我。動態方法的實例?
動態方法的實例?
回答
您可以通過DynamicMethod類創建一個方法。
DynamicMethod squareIt = new DynamicMethod(
"SquareIt",
typeof(long),
methodArgs,
typeof(Example).Module);
ILGenerator il = squareIt.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Conv_I8);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Ret);
Fully commented example on MSDN
我要指出,使用這種方法的發展是非常緩慢的,而不是非常有用的。
我們使用動態方法來加速反射。 這是我們的反射優化器的代碼。它比直接調用和2000倍的速度是反射調用
public class ReflectionEmitPropertyAccessor
{
private readonly bool canRead;
private readonly bool canWrite;
private IPropertyAccessor emittedPropertyAccessor;
private readonly string propertyName;
private readonly Type propertyType;
private readonly Type targetType;
private Dictionary<Type,OpCode> typeOpCodes;
public ReflectionEmitPropertyAccessor(Type targetType, string property)
{
this.targetType = targetType;
propertyName = property;
var propertyInfo = targetType.GetProperty(property);
if (propertyInfo == null)
{
throw new ReflectionOptimizerException(string.Format("Property \"{0}\" is not found in type "+ "{1}.", property, targetType));
}
canRead = propertyInfo.CanRead;
canWrite = propertyInfo.CanWrite;
propertyType = propertyInfo.PropertyType;
}
public bool CanRead
{
get { return canRead; }
}
public bool CanWrite
{
get { return canWrite; }
}
public Type TargetType
{
get { return targetType; }
}
public Type PropertyType
{
get { return propertyType; }
}
#region IPropertyAccessor Members
public object Get(object target)
{
if (canRead)
{
if (emittedPropertyAccessor == null)
{
Init();
}
if (emittedPropertyAccessor != null) return emittedPropertyAccessor.Get(target);
}
else
{
throw new ReflectionOptimizerException(string.Format("У свойства \"{0}\" нет метода get.", propertyName));
}
throw new ReflectionOptimizerException("Fail initialize of " + GetType().FullName);
}
public void Set(object target, object value)
{
if (canWrite)
{
if (emittedPropertyAccessor == null)
{
Init();
}
if (emittedPropertyAccessor != null) emittedPropertyAccessor.Set(target, value);
}
else
{
throw new ReflectionOptimizerException(string.Format("Property \"{0}\" does not have method set.", propertyName));
}
throw new ReflectionOptimizerException("Fail initialize of " + GetType().FullName);
}
#endregion
private void Init()
{
InitTypeOpCodes();
var assembly = EmitAssembly();
emittedPropertyAccessor = assembly.CreateInstance("Property") as IPropertyAccessor;
if (emittedPropertyAccessor == null)
{
throw new ReflectionOptimizerException("Shit happense in PropertyAccessor.");
}
}
private void InitTypeOpCodes()
{
typeOpCodes = new Dictionary<Type, OpCode>
{
{typeof (sbyte), OpCodes.Ldind_I1},
{typeof (byte), OpCodes.Ldind_U1},
{typeof (char), OpCodes.Ldind_U2},
{typeof (short), OpCodes.Ldind_I2},
{typeof (ushort), OpCodes.Ldind_U2},
{typeof (int), OpCodes.Ldind_I4},
{typeof (uint), OpCodes.Ldind_U4},
{typeof (long), OpCodes.Ldind_I8},
{typeof (ulong), OpCodes.Ldind_I8},
{typeof (bool), OpCodes.Ldind_I1},
{typeof (double), OpCodes.Ldind_R8},
{typeof (float), OpCodes.Ldind_R4}
};
}
private Assembly EmitAssembly()
{
var assemblyName = new AssemblyName {Name = "PropertyAccessorAssembly"};
var newAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var newModule = newAssembly.DefineDynamicModule("Module");
var dynamicType = newModule.DefineType("Property", TypeAttributes.Public);
dynamicType.AddInterfaceImplementation(typeof(IPropertyAccessor));
dynamicType.DefineDefaultConstructor(MethodAttributes.Public);
var getParamTypes = new[] { typeof(object) };
var getReturnType = typeof(object);
var getMethod = dynamicType.DefineMethod("Get",
MethodAttributes.Public | MethodAttributes.Virtual,
getReturnType,
getParamTypes);
var getIL = getMethod.GetILGenerator();
var targetGetMethod = targetType.GetMethod("get_" + propertyName);
if (targetGetMethod != null)
{
getIL.DeclareLocal(typeof(object));
getIL.Emit(OpCodes.Ldarg_1); //Load the first argument
getIL.Emit(OpCodes.Castclass, targetType); //Cast to the source type
getIL.EmitCall(OpCodes.Call, targetGetMethod, null); //Get the property value
if (targetGetMethod.ReturnType.IsValueType)
{
getIL.Emit(OpCodes.Box, targetGetMethod.ReturnType); //Box
}
getIL.Emit(OpCodes.Stloc_0); //Store it
getIL.Emit(OpCodes.Ldloc_0);
}
else
{
getIL.ThrowException(typeof(MissingMethodException));
}
getIL.Emit(OpCodes.Ret);
var setParamTypes = new[] { typeof(object), typeof(object) };
const Type setReturnType = null;
var setMethod = dynamicType.DefineMethod("Set",
MethodAttributes.Public | MethodAttributes.Virtual,
setReturnType,
setParamTypes);
var setIL = setMethod.GetILGenerator();
var targetSetMethod = targetType.GetMethod("set_" + propertyName);
if (targetSetMethod != null)
{
Type paramType = targetSetMethod.GetParameters()[0].ParameterType;
setIL.DeclareLocal(paramType);
setIL.Emit(OpCodes.Ldarg_1); //Load the first argument //(target object)
setIL.Emit(OpCodes.Castclass, targetType); //Cast to the source type
setIL.Emit(OpCodes.Ldarg_2); //Load the second argument
//(value object)
if (paramType.IsValueType)
{
setIL.Emit(OpCodes.Unbox, paramType); //Unbox it
if (typeOpCodes.ContainsKey(paramType)) //and load
{
var load = typeOpCodes[paramType];
setIL.Emit(load);
}
else
{
setIL.Emit(OpCodes.Ldobj, paramType);
}
}
else
{
setIL.Emit(OpCodes.Castclass, paramType); //Cast class
}
setIL.EmitCall(OpCodes.Callvirt,targetSetMethod, null); //Set the property value
}
else
{
setIL.ThrowException(typeof(MissingMethodException));
}
setIL.Emit(OpCodes.Ret);
// Load the type
dynamicType.CreateType();
return newAssembly;
}
}
實現從不同來源聚集,主要是這CodeProject上的文章僅慢10%。
謝謝@@ Sergey Miroda ... onw more thing動態方法和反射之間有任何關係 – Pankaj 2009-12-25 09:40:37
是的。 Reflection.Emit是.net反射的一部分。 – 2009-12-25 17:25:50
如果您想在運行時構建可以被垃圾收集的代碼,動態方法也是__only__方法。 – 2009-12-25 17:49:43
- 1. 動態訪問實例方法
- 2. Mongoose'靜態'方法與'實例'方法
- 3. 靜態方法和實例方法C#
- 4. 在實例方法中動態定義一個方法
- 5. 靜態方法vs靜態實例
- 6. 的Python:任何不妥動態分配的實例方法的實例屬性
- 7. 靜態方法或實例方法中的實際代碼
- 8. Python中的靜態和實例方法
- 9. 靜態方法的Java實例變量
- 10. 動態調用上的類的一個實例的方法(用戶指定動態地實例名)
- 11. 調用實例方法的實例方法調用實例方法
- 12. 更改動態方法中的實例變量(使用ActiveResource的動態資源)
- 13. 動態添加實例方法無法訪問類變量
- 14. 如何動態更新實例數組來保存實例化的動態方法列表?
- 15. ruby - 如何動態調用模塊中的實例方法
- 16. 模擬動態分配實例上的方法?
- 17. 在Rails中動態定義關注中的實例方法
- 18. 爲Python中的實例動態創建方法
- 19. 在Ruby中動態添加(預定義的)實例方法
- 20. 帶繼承的動態類和方法實例化
- 21. 如何動態定義ruby中的實例方法?
- 22. 在對象實例化過程中動態加載實例方法
- 23. 在java中的靜態方法vs實例方法的決定?
- 24. ActionScript 3 - 靜態與實例方法
- 25. 從靜態方法實例化子類
- 26. python方法查找,靜態與實例
- 27. Java靜態/實例方法優化
- 28. PHP - 靜態與實例方法
- 29. 類實例調用靜態方法
- 30. C#靜態方法vs對象實例
我不明白朮語_dynamic method_。 Delphi有動態方法,對此C#沒有類比,並且有一種編程技術叫做_dynamic programming_。或者你的意思是_virtual method_? 我假設,「Reflation」是指反射。 – 2009-12-25 07:36:29
沒有人在那裏也有一個動態方法的概念# – Pankaj 2009-12-25 07:38:30