处理隐蔽的类或类的隐蔽属性TypeHelper

Author:水如烟  

也见论坛贴子,你知道吗 

这个类是用来处理隐蔽的类或类的隐蔽属性。说实话,我并不想将它贴出来。但后面的很多处理,都需要它。所以贴了出来。
不想贴出来,并非是它有什么高深的技术,相反,它非常简单。不想贴的原因是,它反映的“歪道”思路可能影响你对.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  _
                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

        
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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值