Voglio imparare il metodo dinamico e il suo esempio pratico usando C#.
Esiste qualche relazione tra il metodo dinamico e Reflection?
Per favore aiutatemi.Esempio pratico di metodo dinamico?
risposta
È possibile creare un metodo tramite la classe 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
Vorrei sottolineare che lo sviluppo di questo metodo è molto lento e non molto utile.
@VMAtm .. avevo letto qualche articolo di DynamicMethod, da qualche parte ho scoperto che sono più veloci della reflection.DynamicMethod eliminano anche la necessità di scrivere codice di serializzazione e deserializzazione personalizzato. – Pankaj
Intendo la velocità di sviluppo: non è molto veloce e molto difficile mantenere tale codice. – VMAtm
ILGenerator - è una parte di System.Reflection.Emit In qualche modo è una relazione tra Reflection e metodi dinamici – VMAtm
Utilizziamo i metodi dinamici per accelerare la riflessione. Ecco il codice del nostro ottimizzatore di riflessione. è solo il 10% più lento di chiamata diretta e 2000 volte più veloce che la chiamata riflessione
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;
}
}
implementazione è aggregato da diverse fonti e principale è questo articolo CodeProject.
Grazie @@Seyy Miroda ... onw more thing Esiste una relazione tra metodo dinamico e Reflection – Pankaj
Sì, lo è. Reflection.Emit è una parte di .net reflection. –
anche il metodo dinamico è il modo __only__ se si desidera eseguire il runtime nel codice di costruzione che può essere sottoposto a garbage collection. –
- 1. Comprendere BDD con un esempio pratico
- 2. Uso pratico di un tipo dinamico in Scala
- 3. Qualche esempio pratico di riferimento lungo e debole?
- 4. Viene utilizzato un esempio pratico di LockSupport e AbstractQueuedSynchronizer?
- 5. Dove posso trovare un esempio pratico di client Javascript HATEOAS?
- 6. Simple Object vs fabbrica vs Constructor - Esempio pratico
- 7. Uso pratico di `foldl`
- 8. Chiamata di metodo dinamico in Objective-C
- 9. Rifacimento pratico con test unitari
- 10. Esempio di un metodo di istanza? (Java)
- 11. È necessario un esempio pratico di configurazione di log4j RollingFileAppender tramite le proprietà
- 12. Codice di esempio su UIApplicationShortcutItems dinamico (Objective-C)
- 13. Esempi di utilizzo pratico di Boost :: MPL?
- 14. HTTP metodo PUT struttura esempio
- 15. Uso pratico di Android XmlResourceParser?
- 16. Utilizzo pratico efficiente di IBOutletColletion
- 17. utilizzo pratico di params indicizzatore
- 18. Liskov principio di sostituzione - metodo prioritario esempio
- 19. Esempio di riferimento del metodo in JLS
- 20. Uso pratico degli eventi di interfaccia
- 21. Toolkit GUI pratico?
- 22. Modo pratico di spiegare "Teoria dell'informazione"
- 23. Recupero dinamico del nome del metodo corrente
- 24. Ritorno dinamico Tipo in metodo Java
- 25. Il tentativo di associare un metodo dinamico a un assieme creato in modo dinamico causa una RuntimeBinderException
- 26. Quale metodo di interpolazione multivariata è il migliore per l'uso pratico?
- 27. Un array 2D dinamico può implementare il metodo Java.Collection.size()?
- 28. Esempio di Disruptor.NET
- 29. Qual è l'uso pratico della colonna timestamp in SQL Server con esempio?
- 30. somiglianze e le differenze tra vettori e puntatori attraverso un esempio pratico
Non capisco il termine _ metodo dinamico_. Delphi ha metodi dinamici, per i quali C# non ha analogie, e c'è una tecnica di programmazione chiamata _dynamic programming_. O intendi il metodo virtuale? Presumo, per "Riflazione", si intende la riflessione. –
no man c'è anche un concetto di metodo dinamico in C# – Pankaj