Tôi muốn tìm hiểu phương pháp động và ví dụ thực tế của nó bằng cách sử dụng C#.
Có mối quan hệ nào giữa phương pháp động và Phản xạ không?
Xin hãy giúp tôi.Ví dụ thực tế về phương pháp động?
Trả lời
Bạn có thể tạo phương thức qua lớp 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
tôi nên lưu ý rằng sự phát triển sử dụng phương pháp này là rất chậm và không phải là rất hữu ích.
@VMAtm .. tôi đã đọc một số bài viết của DynamicMethod, một nơi nào đó tôi thấy rằng họ là nhanh hơn sau đó reflection.DynamicMethod họ cũng loại bỏ sự cần thiết phải viết serialization & deserialization mã tùy chỉnh. – Pankaj
Tôi có nghĩa là tốc độ phát triển - nó không phải là rất nhanh và rất khó để duy trì mã như vậy. – VMAtm
ILGenerator - là một phần của System.Reflection.Emit Trong phần nào nó là một mối quan hệ giữa Reflection và phương pháp năng động – VMAtm
Chúng tôi đang sử dụng các phương pháp động để tăng tốc độ phản ánh. Đây là mã của trình tối ưu hóa phản chiếu của chúng tôi. nó chỉ chậm hơn 10% so với cuộc gọi trực tiếp và nhanh hơn 2000 lần so với cuộc gọi phản chiếu
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;
}
}
thực hiện được tổng hợp từ các nguồn khác nhau và chính là bài viết CodeProject này.
Cảm ơn @@ Sergey Miroda ... onw nhiều điều Có mối quan hệ nào giữa phương pháp động và Reflection – Pankaj
Có đúng vậy. Reflection.Emit là một phần của sự phản chiếu .net. –
cũng là phương pháp động là cách __only__ nếu bạn muốn chạy thi công mã có thể được thu thập rác. –
- 1. Ví dụ thực tế về đa hình
- 2. Ví dụ về các phương pháp và vòng đời thực tế
- 3. Ví dụ thực tế về sử dụng NLTK
- 4. Ví dụ thực tế về ACID là gì?
- 5. Ví dụ thực tế về xvalues, glvalues và prvalues?
- 6. Ví dụ thực tế của Idris
- 7. JAXB @XmlAttribute @XmlValue ví dụ thực tế
- 8. PHP: Ví dụ OOP thực tế
- 9. Ví dụ thực tế về sự kiện Lỗi dấu chấm động
- 10. Ví dụ về một phương pháp thể hiện? (Java)
- 11. Scala contravariance - ví dụ thực tế đời sống
- 12. Tôi cần nhiều ví dụ thực tế hơn Ninject
- 13. Tìm kiếm các ví dụ thực tế Gradle
- 14. Hiểu BDD với một ví dụ thực tế
- 15. R demo() và ví dụ() phương pháp?
- 16. Lớp học - ví dụ so với phương pháp lớp học
- 17. Ví dụ thực tế cuộc sống cho CountDownLatch và CyclicBarrier
- 18. Ví dụ về thuộc tính so với phương pháp trong JS
- 19. Ví dụ về sử dụng phổ biến, thực tế của sự kiện bong bóng và chụp?
- 20. Một số ví dụ về đời sống thực tế được sử dụng trong phần mềm
- 21. Ví dụ thực tế về đời sống của CORBA là gì?
- 22. nơi để tìm một ví dụ thực tế về flex và bò rừng?
- 23. Bất kỳ ví dụ thực tế nào về sử dụng LockSupport & AbstractQueuedSynchronizer?
- 24. Ví dụ về cách sử dụng thực tế của Boost :: MPL?
- 25. Ví dụ về truyền tải cây trước/sau đặt hàng thực tế
- 26. Ví dụ về MultiSelectListPreference
- 27. Ví dụ về Winsock?
- 28. Ví dụ về JGraphT
- 29. Ví dụ về D.ccurl
- 30. Ví dụ về pysmb
Tôi không hiểu thuật ngữ _dynamic method_. Delphi có các phương thức động, trong đó C# không có sự tương tự, và có một kỹ thuật lập trình được gọi là _dynamic programming_. Hay bạn có nghĩa là _virtual method_? Tôi giả sử, bằng cách "Từ chối", bạn có nghĩa là phản chiếu. –
không có người đàn ông cũng có một khái niệm về phương pháp năng động trong C# – Pankaj