正如问题中所指出的,我感兴趣的是使用.net的动态特性来缓存对象的字段getter/setter并在运行时调用它。
使用来自:Is there a way to create a delegate to get and set values for a FieldInfo?的信息
我已经设置了一个类和函数来设置我需要的功能:
Public Class c1
Public someField As Integer 'we will Get the value of this dynamically
End Class
Public Function CreateGetter(Of S, T)(ByVal strFieldName As String) As Func(Of S, T)
'creates a function to return the value
Dim objFieldInfo As FieldInfo
Dim strMethodName As String
Dim objGetterMethod As DynamicMethod
Dim objGen As ILGenerator
objFieldInfo = GetType(S).GetField(strFieldName)
strMethodName = Convert.ToString(objFieldInfo.ReflectedType.FullName) & ".get_" & Convert.ToString(objFieldInfo.Name)
objGetterMethod = New DynamicMethod(strMethodName, GetType(T), New Type(0) {GetType(S)}, True)
objGen = objGetterMethod.GetILGenerator()
If objFieldInfo.IsStatic = False Then
objGen.Emit(OpCodes.Ldarg_0)
objGen.Emit(OpCodes.Ldfld, objFieldInfo)
Else
objGen.Emit(OpCodes.Ldsfld, objFieldInfo)
End If
objGen.Emit(OpCodes.Ret)
Return DirectCast(objGetterMethod.CreateDelegate(GetType(Func(Of S, T))), Func(Of S, T))
End Function我把这个好代码称为:
Dim getValue = CreateGetter(Of c1, Integer)("someField")
Dim someValue As Integer
someValue = getValue(o1)然而,我感到困惑的部分是如何修改函数CreateGetter,以便能够在缓存的形式中使用它,比如:(缓存实例对象)。
Dim getValue = CreateGetter(Of c1, Integer)(o1,"someField")
Dim someValue As Integer
someValue = getValue()我意识到这可能需要对CreateGetter中的IL代码进行一些修改,但这是我一直坚持的棘手的部分。
发布于 2014-08-08 11:36:36
实际上,你不能用一种方法来做这件事。要永久保存该对象,您需要在某个对象中添加一个字段,然后创建一个指向该对象上的某个方法的委托。
您可以使用Reflection.Emit完成所有这些工作,但这将是一件乏味的事情。相反,您可以利用编译器已经可以这样做来创建闭包的事实:不是直接返回DynamicMethod委托,而是返回调用该委托的lambda:
Dim fieldAccessor = DirectCast(objGetterMethod.CreateDelegate(GetType(Func(Of S, T))), Func(Of S, T))
Return Function() fieldAccessor(obj)另一种选择是为所有这些使用表达式树。这有一个优点,你不必处理IL,这可能是很难得到正确的。类似于:
Function CreateGetter(Of S, T)(obj as S, fieldName As String) As Func(Of T)
Dim expr = Expression.Lambda(Of Func(Of T))(
Expression.Field(Expression.Constant(obj), fieldName))
Return expr.Compile()
End Function这个版本只适用于实例字段,我认为对于静态字段,不需要obj的重载更有意义。
https://stackoverflow.com/questions/25188178
复制相似问题