程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 處理隱蔽的類或類的隱蔽屬性TypeHelper

處理隱蔽的類或類的隱蔽屬性TypeHelper

編輯:.NET實例教程
這個類是用來處理隱蔽的類或類的隱蔽屬性。說實話,我並不想將它貼出來。但後面的很多處理,都需要它。所以貼了出來。
不想貼出來,並非是它有什麼高深的技術,相反,它非常簡單。不想貼的原因是,它反映的“歪道”思路可能影響你對.Net的理解。

我不是編程或者是真正意義上的IT職員,我學習.NET應用.Net僅僅是用來保持自己的腦袋還處於思索狀態,不至於因生活而麻木。
況且,我只接觸WinForm。我學習.Net的興趣就來源於走“歪道”。切記,僅供參考。

TypeHelper.vb



Imports System.Reflection

Namespace LzmTW.uSystem.uReflection

    Public Class TypeHelper

        Private gType As Type
        Private gCurrentObjct As Object

        Public ReadOnly Property CurrentType() As Type
            Get
                Return gType
            End Get
        End Property

        Public ReadOnly Property CurrentObject() As Object
            Get
                Return gCurrentObjct
            End Get
        End Property


        Sub New(ByVal referrenceObj As Object)
            If Me.IsType(referrenceObj) Then

                Me.gType = CType(referrenceObj, Type)
            Else

                Me.gType = referrenceObj.GetType
                Me.gCurrentObjct = referrenceObj
            End If
        End Sub

        Sub New(ByVal assembly As Assembly, ByVal fullTypeName As String)
            Me.InternalCreate(assembly, fullTypeName)

            Me.InternalCheckIsValid(fullTypeName, True)
        End Sub

        Sub New(ByVal referrenceType As Type, ByVal typeName As String, Optional ByVal isNestedType As Boolean = False)

            Dim mAssembly As Assembly = referrenceType.Assembly

            Me.InternalCreate(mAssembly, typeName)

            If Me.InternalCheckIsValid(typeName, False) Then Return

            Dim mFullTypeName As String = GetFullTypeName(referrenceType, typeName, isNestedType)

            Me.InternalCreate(mAssembly, mFullTypeName)

            Me.InternalCheckIsValid(mFullTypeName, True)
        End Sub

        Private Sub InternalCreate(ByVal ass As Assembly, ByVal fulltypename As String)
            gType = ass.GetType(fulltypename, False, True)
        End Sub

        Private Function InternalCheckIsValid(ByVal typename As String, ByVal throwOnError As Boolean) As Boolean
            If gType Is Nothing Then
                If throwOnError Then
                    Throw New ArgumentException(String.Format("typeName: {0} 不存在", typename))
                Else
                    Return False
                End If
            End If

            Return True
        End Function

        Private Function GetFullTypeName(ByVal referrenceType As Type, ByVal typeName As String, ByVal isNestedType As Boolean) As String
            Dim mFullName As String = Nothing

            Dim mRefFullName As String = referrenceType.FullName

            If isNestedType Then

                mFullName = String.Concat(mRefFullName, "+", typeName)
            Else

                Dim mLastIndex As Integer = mRefFullName.LastIndexOf(referrenceType.Name)

                mFullName = String.Concat(mRefFullName.Substring(0, mLastIndex), typeName)
            End If

            Return mFullName
        End Function

        Private Function IsType(ByVal instance As Object) As Boolean
            Return instance.GetType.IsSubclassOf(GetType(Type))
        End Function

        Public Const Binding As BindingFlags = _
            BindingFlags.Instance Or _
            BindingFlags.Public Or _
            BindingFlags.NonPublic Or _
            BindingFlags.Static Or _
            BindingFlags.CreateInstance Or _
            BindingFlags.IgnoreCase


    End Class

End Namespace

TypeHelper.Methods.vb



Imports System.Reflection

Namespace LzmTW.uSystem.uReflection

    Partial Class TypeHelper

        Public Sub SetCurrentObj(ByVal obj As Object)
            If Not obj Is Nothing AndAlso Not Me.CurrentType.IsInstanceOfType(obj) Then
                Throw New ArgumentException("實例類型與內部類型不相符")
            End If

            Me.gCurrentObjct = obj
        End Sub

        Public Function GetMemberValue(ByVal name As String, ByVal ParamArray args() As Object) As Object
            Return Me.CurrentType.InvokeMember( _
                name, _
                MemberGetBinding, _
                Nothing, _
                Me.CurrentObject, _
                args)
        End Function


        Public Sub SetMemberValue(ByVal name As String, ByVal ParamArray args() As Object)
            Me.CurrentType.InvokeMember( _
                name, _
                MemberSetBinding, _
                Nothing, _
                Me.CurrentObject, _
                args)
        End Sub

        Public Function MethodInvoke(ByVal name As String, ByVal ParamArray args() As Object) As Object
            Return Me.CurrentType.InvokeMember( _
                name, _
                MethodBinding, _
                Nothing, _
                Me.CurrentObject, _
                args)
        End Function

        Public Function NewInstance(ByVal ParamArray args() As Object) As Object
            Dim mParaCount As Integer = args.Length
            Dim mCtors As ConstructorInfo() = Me.CurrentType.GetConstructors(MethodBinding)

            For Each ctro As ConstructorInfo In mCtors
                If ctro.GetParameters.Length = mParaCount Then
                    Return ctro.Invoke(args)
                End If
            Next

            Return Nothing
        End Function

        '''''' <summary>
        '''''' 可以使用*?[abc][!abc],忽略大小寫
        '''''' </summary>
        Public Function FindMember(ByVal name As String) As MemberInfo()
            If String.IsNullOrEmpty(name) OrElse name = "*" Then
                Return Me.CurrentType.GetMembers(Binding)
            End If

            Dim mPattern As String = "*[*?]*"
            If Not name Like mPattern Then Return Me.CurrentType.GetMember(name, Binding)

            Dim mArray As New List(Of MemberInfo)
            For Each m As MemberInfo In Me.CurrentType.GetMembers(Binding)
                If m.Name.ToLower Like name.ToLower Then
                    mArray.Add(m)
                End If
            Next

            Return mArray.ToArray
        End Function


        Private MemberGetBinding As BindingFlags = _
                BindingFlags.Instance Or _
                BindingFlags.Public Or _
                BindingFlags.NonPublic Or _
                BindingFlags.Static Or _
                BindingFlags.GetFIEld Or _
                BindingFlags.GetProperty Or _
                BindingFlags.IgnoreCase

        Private MemberSetBinding As BindingFlags = _
                BindingFlags.Instance Or _
                BindingFlags.Public Or _
    &nbsp;           BindingFlags.NonPublic Or _
                BindingFlags.Static Or _
                BindingFlags.SetFIEld Or _
                BindingFlags.SetProperty Or _
                BindingFlags.IgnoreCase

        Private MethodBinding As BindingFlags = _
                BindingFlags.Instance Or _
                BindingFlags.Public Or _
                BindingFlags.NonPublic Or _
                BindingFlags.Static Or _
                BindingFlags.InvokeMethod Or _
                BindingFlags.IgnoreCase
    End Class

End Namespace

 

TypeHelper.Shared.vb



Imports System.Reflection

Namespace LzmTW.uSystem.uReflection

    Partial Class TypeHelper

        Public Shared Function HGetMemberValue(ByVal obj As Object, ByVal name As String, ByVal ParamArray args() As Object) As Object
            Dim mHelper As New TypeHelper(obj)
            Return mHelper.GetMemberValue(name, args)
        End Function

        Public Shared Sub HSetMemberValue(ByVal obj As Object, ByVal name As String, ByVal ParamArray args() As Object)
            Dim mHelper As New TypeHelper(obj)
            mHelper.SetMemberValue(name, args)
        End Sub

        Public Shared Function HMethodInvoke(ByVal obj As Object, ByVal name As String, ByVal ParamArray args() As Object) As Object
            Dim mHelper As New TypeHelper(obj)
            Return mHelper.MethodInvoke(name, args)
        End Function

        Public Shared Function HNewInstance(ByVal refobj As Object, ByVal ParamArray args() As Object) As Object
            Dim mHelper As New TypeHelper(refobj)
            Return mHelper.NewInstance(args)
        End Function

        Public Shared Function HFindMember(ByVal obj As Object, ByVal name As String) As MemberInfo()
            Dim mHelper As New TypeHelper(obj)
            Return mHelper.FindMember(name)
        End Function

    End Class

End Namespace

上面說到“歪道”,在下面一個例子可以看到。

注:變量的安全問題我曾經想過“研究”一番,可最後還是沒研下來,因為我覺得那些東西太費腦了,有點吃力。

示例:怎麼保證User的信息安全



Imports System.Security
Imports System.Runtime.InteropServices

Public Class User
    Private gName As String
    Private gPassWord As SecureString

    Sub New(ByVal name As String, ByVal passWord As String)
        Me.gName = name

        Me.gPassWord = New SecureString
        For Each c As Char In passWord.ToCharArray
            Me.gPassWord.AppendChar(c)
        Next

        Me.gPassWord.MakeReadOnly()
    ;End Sub

    Public ReadOnly Property Name() As String
        Get
            Return gName
        End Get
    End Property

    Public ReadOnly Property PassWord() As String
        Get
            Return Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(gPassWord))
        End Get
    End Property

    Public Overloads Function ToString()
        Return String.Format("my name is {0}, pass is {1} ", Me.Name, Me.PassWord)
    End Function
End Class

測試:



Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim t As New User("LzmTW", "bybyMycsdn")

        Login(t)

        ''changed
        Dim helper As New LzmTW.uSystem.uReflection.TypeHelper(t)

        Console.WriteLine("name changed!")
        helper.SetMemberValue("gname", "lzm")
        Login(t)

        Dim tmp As New Security.SecureString
        tmp.AppendChar("h")
        tmp.AppendChar("e")
        tmp.AppendChar("h")
        tmp.AppendChar("e")

        Console.WriteLine("pass changed!")
        helper.SetMemberValue("gPassWord", tmp)
        Login(t)


    End Sub

    Private Sub Login(ByVal user As User)
        Console.WriteLine(user.ToString)
        Console.WriteLine()
    End Sub
End Class

結果:

my name is LzmTW, pass is bybyMycsdn


name changed!
my name is lzm, pass is bybyMycsdn


pass changed!
my name is lzm, pass is hehe

對於構造函數是私有的類,我們也能實例化

示例:



Imports System.Security
Imports System.Runtime.InteropServices

Public Class User
    Private gName As String
    Private gPassWord As SecureString

   ''注意構造函數是私有的
    Private Sub New(ByVal name As String, ByVal passWord As String)
        Me.gName = name

        Me.gPassWord = New SecureString
        For Each c As Char In passWord.ToCharArray
            Me.gPassWord.AppendChar(c)
        Next

        Me.gPassWord.MakeReadOnly()
    End Sub

    Public ReadOnly Property Name() As String
        Get
            Return gName
        End Get
    End Property

    Public ReadOnly Property PassWord() As String
        Get
            Return Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(gPassWord))
        End Get
    End Property

    Public Overloads Function ToString()
        Return String.Format("my name is {0}, pass is {1} ", Me.Name, Me.PassWord)
    End Function
End Class

測試:



Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim t As User

&nbsp;       Dim helper As New LzmTW.uSystem.uReflection.TypeHelper(GetType(User))

        ''create instance
        t = CType(helper.NewInstance("LzmTW", "Hello"), User)

        Login(t)


    End Sub

    Private Sub Login(ByVal user As User)
        Console.WriteLine(user.ToString)
        Console.WriteLine()
    End Sub
End Class


結果:

my name is LzmTW, pass is Hello



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved