VB > Reflection.Emit: наследовать от суперкласса и переопределить метод
Я сам пытался написать этот очень простой код, но он мне немного сложен (Reflection.Emit очень нов для меня), так что я здесь. Что мне нужно, так это целый класс, который наследует от суперкласса и переопределяет метод - все написано для того, чтобы создаваться и создаваться во время выполнения.
Мой суперкласс, ClassA, является пустым классом без кода, кроме идентификатора реализации:
Namespace Basic
Public Class ClassA
Implements IDisposable
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
End Namespace
Мой ClassB - тот, который будет создан во время выполнения. Это должно выглядеть так:
Namespace Basic
Public Class ClassB
Inherits ClassA
Protected Overrides Sub Dispose(disposing As Boolean)
MyBase.Dispose(disposing)
End Sub
End Class
End Namespace
Я много искал и не могу узнать, как написать код наследования при создании ClassB на лету. Кроме того, я не уверен в написании сегмента вызова в OPCode для ClassB
.method family strict virtual instance void
Dispose(bool disposing) cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: call instance void WindowsApplication1.Basic.ClassA::Dispose(bool)
IL_0008: nop
IL_0009: nop
IL_000a: ret
} // end of method ClassB::Dispose
Кто-нибудь?
1 ответ
Это то, что мне нужно. Этот класс содержит iDisposable:
Public Class Super
Implements IDisposable
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
For Each prop As PropertyInfo In Me.GetType.GetProperties
If prop.CanWrite Then
prop.SetValue(Me, Nothing, Nothing)
End If
Next
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Overridable Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
... и это мой класс строитель, который наследует от супер
Public Class ClassCreator
Public Shared Function CreateClass() As Object
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")
Thread.CurrentThread.CurrentUICulture = New CultureInfo("en-US")
Dim name As String = "DefineMethodOverrideExample"
Dim myAssemblyName As New AssemblyName(name)
Dim myAssemblyBuilder As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave)
Dim myModuleBuilder As ModuleBuilder = myAssemblyBuilder.DefineDynamicModule(name, name & ".dll")
Dim myTypebuilder As TypeBuilder = myModuleBuilder.DefineType("C", TypeAttributes.Public, GetType(Super))
Dim myMethodBuilder As MethodBuilder = myTypebuilder.DefineMethod("Dispose",
MethodAttributes.Public Or MethodAttributes.ReuseSlot Or MethodAttributes.Virtual Or MethodAttributes.HideBySig,
Nothing,
Type.EmptyTypes)
Dim il As ILGenerator = myMethodBuilder.GetILGenerator()
il = myMethodBuilder.GetILGenerator()
il.Emit(OpCodes.Nop)
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Call, GetType(Super).GetMethod("Dispose"))
il.Emit(OpCodes.Nop)
il.Emit(OpCodes.Nop)
il.Emit(OpCodes.Ret)
Dim tc As Type = myTypebuilder.CreateType()
myAssemblyBuilder.Save(name & ".dll")
Dim test As Object = Activator.CreateInstance(tc)
Return test
End Function
End Class
Конструктор классов создает классы, которые можно утилизировать, чего я и хотел:)