0

私はこの非常に単純なコードを自分で書こうとしてきましたが、少し難しいと感じました (Reflection.Emit は私にとって非常に新しいものです)。私が必要としているのは、スーパー クラスから継承し、メソッドをオーバーライドするクラス全体です。これらはすべて、実行時に発行および作成されるように記述されています。

私のスーパー クラスである ClassA は、Implement IDispose を除いてコードのない空のクラスです。

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 をその場で作成するときに、継承コードを記述する方法がわかりません。また、ClassB の OPCode に call-segment を記述することについてはよくわかりません。

.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

誰?

4

1 に答える 1

0

これは私が思いついたものです。このクラスは 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

...そして、これは Super から継承する私のクラス ビルダーです。

 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

クラスビルダーは、私が望んでいた、破棄できるクラスを構築します:)

于 2013-09-02T13:53:12.580 に答える