2020-03-28 15:44:37 +08:00
|
|
|
|
#Region "Microsoft.VisualBasic::68d490474d5d5d2d807cb8e636708957, Microsoft.VisualBasic.Core\Extensions\Reflection\Reflection.vb"
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
' Author:
|
|
|
|
|
|
'
|
|
|
|
|
|
' asuka (amethyst.asuka@gcmodeller.org)
|
|
|
|
|
|
' xie (genetics@smrucc.org)
|
|
|
|
|
|
' xieguigang (xie.guigang@live.com)
|
|
|
|
|
|
'
|
|
|
|
|
|
' Copyright (c) 2018 GPL3 Licensed
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' GNU GENERAL PUBLIC LICENSE (GPL3)
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is free software: you can redistribute it and/or modify
|
|
|
|
|
|
' it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
' the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
' (at your option) any later version.
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
' but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
' GNU General Public License for more details.
|
|
|
|
|
|
'
|
|
|
|
|
|
' You should have received a copy of the GNU General Public License
|
|
|
|
|
|
' along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
' Summaries:
|
|
|
|
|
|
|
|
|
|
|
|
' Module EmitReflection
|
|
|
|
|
|
'
|
2020-03-28 15:44:37 +08:00
|
|
|
|
' Function: AsLambda, Collection2GenericIEnumerable, (+2 Overloads) CreateObject, (+3 Overloads) Description, FullName
|
|
|
|
|
|
' (+3 Overloads) GetAssemblyDetails, (+2 Overloads) GetAttribute, GetDelegateInvokeEntryPoint, GetFullName, (+2 Overloads) GetReadWriteProperties
|
|
|
|
|
|
' GetTypeElement, GetTypesHelper, (+2 Overloads) GetVersion, IsInheritsFrom, IsModule
|
|
|
|
|
|
' IsNonParametric, IsNumericType, ModuleVersion, ResourcesSatellite, Source
|
2018-08-02 20:14:48 +08:00
|
|
|
|
'
|
2019-08-04 22:25:57 +08:00
|
|
|
|
' Sub: RunApp, runAppInternal
|
2018-08-02 20:14:48 +08:00
|
|
|
|
'
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
Imports System.ComponentModel
|
|
|
|
|
|
Imports System.Reflection
|
|
|
|
|
|
Imports System.Runtime.CompilerServices
|
|
|
|
|
|
Imports Microsoft.VisualBasic.ApplicationServices
|
|
|
|
|
|
Imports Microsoft.VisualBasic.ApplicationServices.Development
|
|
|
|
|
|
Imports Microsoft.VisualBasic.CommandLine.Reflection
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Emit.Delegates
|
|
|
|
|
|
Imports Microsoft.VisualBasic.FileIO
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Language
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Language.Default
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Linq
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Scripting
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Scripting.MetaData
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Serialization.JSON
|
|
|
|
|
|
Imports DevAssmInfo = Microsoft.VisualBasic.ApplicationServices.Development.AssemblyInfo
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Some common used reflection operation extension at here.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
<Package("Emit.Reflection", Category:=APICategories.SoftwareTools, Publisher:="xie.guigang@live.com")>
|
|
|
|
|
|
Public Module EmitReflection
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function ResourcesSatellite(assembly As Assembly) As ResourcesSatellite
|
|
|
|
|
|
Return New ResourcesSatellite(assembly)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-02-19 18:25:51 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 这个方法的调用是否是不需要任何参数的?
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="method"></param>
|
|
|
|
|
|
''' <param name="optionalAsNone"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function IsNonParametric(method As MethodInfo, Optional optionalAsNone As Boolean = False) As Boolean
|
|
|
|
|
|
Dim params = method.GetParameters
|
|
|
|
|
|
|
|
|
|
|
|
If params.IsNullOrEmpty Then
|
|
|
|
|
|
Return True
|
|
|
|
|
|
ElseIf optionalAsNone Then
|
|
|
|
|
|
Return Not params.Any(Function(p) Not p.IsOptional)
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Return False
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Try to handle for the bugs in VisualBasic language:
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' https://github.com/dotnet/roslyn/issues/23050
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="assm"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Function GetTypesHelper(assm As Assembly) As Type()
|
|
|
|
|
|
Try
|
|
|
|
|
|
Return assm.GetTypes
|
|
|
|
|
|
|
|
|
|
|
|
Catch ex As Exception When TypeOf ex Is ReflectionTypeLoadException
|
|
|
|
|
|
Dim details = DirectCast(ex, ReflectionTypeLoadException)
|
|
|
|
|
|
Dim msg$ = details.LoaderExceptions _
|
|
|
|
|
|
.Select(Function(e) e.Message) _
|
|
|
|
|
|
.ToArray _
|
|
|
|
|
|
.GetJson
|
|
|
|
|
|
|
|
|
|
|
|
Throw New Exception(msg, ex)
|
|
|
|
|
|
|
|
|
|
|
|
Catch ex As Exception
|
|
|
|
|
|
|
|
|
|
|
|
Throw
|
|
|
|
|
|
|
|
|
|
|
|
End Try
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function AsLambda(Of T)(assert As Assert(Of T)) As Func(Of T, Boolean)
|
|
|
|
|
|
' System.ArgumentException: '无法绑定到目标方法,因其签名或安全透明度与委托类型的签名或安全透明度不兼容。
|
|
|
|
|
|
' assert.Method.CreateDelegate(GetType(Func(Of T, Boolean)))
|
|
|
|
|
|
Return Function(x) assert(x)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function Source(m As MemberInfo) As String
|
|
|
|
|
|
Return m.DeclaringType.FullName & "::" & m.Name
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Run external [.NET] Program from RAM Memory
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="app"></param>
|
|
|
|
|
|
''' <param name="CLI"></param>
|
|
|
|
|
|
''' <param name="cs">Going to running a c# program?</param>
|
|
|
|
|
|
''' <remarks>
|
|
|
|
|
|
''' http://www.codeproject.com/Tips/1108105/Run-external-NET-Program-from-RAM-Memory
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' Run external app directly from RAM. You can load the specific file into a ``Byte[]`` Array
|
|
|
|
|
|
''' with a ``StreamReader()`` or even download it from WEB via a direct link provided.
|
|
|
|
|
|
''' If you loaded the file from disk, you can delete it if you want after it has been loaded
|
|
|
|
|
|
''' by a ``StreamReader()``.
|
|
|
|
|
|
''' </remarks>
|
|
|
|
|
|
Public Sub RunApp(app As String, Optional CLI As String = "", Optional cs As Boolean = False)
|
2019-08-03 21:28:16 +08:00
|
|
|
|
' Works on both local file or network file.
|
|
|
|
|
|
Dim bufs As Byte() = app.GetMapPath.ReadBinary
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
Try
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Call bufs.runAppInternal(CLI, isCsApp:=cs)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Catch ex As Exception
|
|
|
|
|
|
ex = New Exception("CLI:=" & CLI, ex)
|
|
|
|
|
|
ex = New Exception("app:=" & app, ex)
|
|
|
|
|
|
#If DEBUG Then
|
|
|
|
|
|
Call ex.PrintException
|
|
|
|
|
|
#End If
|
|
|
|
|
|
Throw ex
|
|
|
|
|
|
End Try
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
<Extension>
|
|
|
|
|
|
Private Sub runAppInternal(app As Byte(), cli$, isCsApp As Boolean)
|
|
|
|
|
|
' or assm = Reflection.Assembly.Load(New WebClient().DownloadData("https://...."))
|
|
|
|
|
|
Dim assm As Assembly = Assembly.Load(app)
|
|
|
|
|
|
Dim method As MethodInfo = assm.EntryPoint
|
|
|
|
|
|
Dim null As Object() = If(isCsApp, {Nothing}, Nothing)
|
|
|
|
|
|
|
|
|
|
|
|
If (Not method Is Nothing) Then
|
|
|
|
|
|
Dim o As Object = assm.CreateInstance(method.Name)
|
|
|
|
|
|
|
|
|
|
|
|
If String.IsNullOrEmpty(cli) Then
|
|
|
|
|
|
Call method.Invoke(o, null)
|
|
|
|
|
|
Else
|
|
|
|
|
|
' if your app receives parameters
|
|
|
|
|
|
Call method.Invoke(o, New Object() {CommandLine.GetTokens(cli)})
|
|
|
|
|
|
End If
|
|
|
|
|
|
Else
|
|
|
|
|
|
Throw New NullReferenceException($"'{app}' No App Entry Point was found!")
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
#Region "IsNumericType"
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Determines whether the specified value is of numeric type.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="o">The object to check.</param>
|
|
|
|
|
|
''' <returns>
|
|
|
|
|
|
''' true if o is a numeric type; otherwise, false.
|
|
|
|
|
|
''' </returns>
|
|
|
|
|
|
Public Function IsNumericType(o As Object) As Boolean
|
|
|
|
|
|
Return (TypeOf o Is Byte OrElse
|
|
|
|
|
|
TypeOf o Is SByte OrElse
|
|
|
|
|
|
TypeOf o Is Short OrElse
|
|
|
|
|
|
TypeOf o Is UShort OrElse
|
|
|
|
|
|
TypeOf o Is Integer OrElse
|
|
|
|
|
|
TypeOf o Is UInteger OrElse
|
|
|
|
|
|
TypeOf o Is Long OrElse
|
|
|
|
|
|
TypeOf o Is ULong OrElse
|
|
|
|
|
|
TypeOf o Is Single OrElse
|
|
|
|
|
|
TypeOf o Is Double OrElse
|
|
|
|
|
|
TypeOf o Is Decimal)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
<ExportAPI("GET.Assembly.Details")>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function GetAssemblyDetails(path As String) As DevAssmInfo
|
|
|
|
|
|
Return Assembly.LoadFile(path).FromAssembly
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<ExportAPI("GET.Assembly.Details")>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function GetAssemblyDetails(def As Type) As DevAssmInfo
|
|
|
|
|
|
Return def.Assembly.FromAssembly
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<ExportAPI("GET.Assembly.Details")>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function GetAssemblyDetails(assm As Assembly) As DevAssmInfo
|
|
|
|
|
|
Return assm.FromAssembly
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 得到集合类型的对象之中的元素类型
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="type"></param>
|
|
|
|
|
|
''' <param name="strict"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<Extension> Public Function GetTypeElement(type As Type, strict As Boolean) As Type
|
|
|
|
|
|
If type.IsInheritsFrom(GetType(Array)) Then
|
|
|
|
|
|
Return type.GetElementType
|
|
|
|
|
|
End If
|
|
|
|
|
|
If type.IsInheritsFrom(GetType(List(Of ))) Then
|
|
|
|
|
|
Return type.GetGenericArguments.First
|
|
|
|
|
|
End If
|
|
|
|
|
|
If type.IsInheritsFrom(GetType(Dictionary(Of ,))) Then
|
|
|
|
|
|
Dim keyValue As Type() = type.GetGenericArguments
|
|
|
|
|
|
Return GetType(KeyValuePair(Of ,)).MakeGenericType(keyValue)
|
|
|
|
|
|
End If
|
|
|
|
|
|
If type.ImplementInterface(GetType(IEnumerable)) Then
|
|
|
|
|
|
type = type.GetInterfaces.Where(Function(i) InStr(i.Name, "IEnumerable") = 1).First
|
|
|
|
|
|
Return type.GenericTypeArguments.First
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
If strict Then
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
Else
|
|
|
|
|
|
Throw New NotImplementedException
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="Product">.NET EXE/DLL assembly path</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<ExportAPI("Get.Version")>
|
|
|
|
|
|
Public Function GetVersion(Product As String) As Version
|
|
|
|
|
|
Dim assm As Assembly = Assembly.LoadFile(Product)
|
|
|
|
|
|
Return assm.GetVersion
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 如果不存在<see cref="DescriptionAttribute"/>定义则会返回空白字符串
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="prop"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<ExportAPI("Get.Description")>
|
|
|
|
|
|
<Extension> Public Function Description(prop As PropertyInfo) As String
|
|
|
|
|
|
Dim attrs As Object() = prop.GetCustomAttributes(GetType(DescriptionAttribute), inherit:=True)
|
|
|
|
|
|
|
|
|
|
|
|
If attrs.IsNullOrEmpty Then
|
|
|
|
|
|
Return ""
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return DirectCast(attrs(Scan0), DescriptionAttribute).Description
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets the <see cref="AssemblyFileVersionAttribute"/> value from the type defined assembly.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="type"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<ExportAPI("Get.Version")>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function ModuleVersion(type As Type) As String
|
|
|
|
|
|
Return type.Assembly.GetVersion.ToString
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="assm">.NET EXE/DLL assembly</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<ExportAPI("Get.Version")>
|
|
|
|
|
|
<Extension> Public Function GetVersion(assm As Assembly) As Version
|
|
|
|
|
|
#If NET_40 = 0 Then
|
|
|
|
|
|
Dim attrs As IEnumerable(Of CustomAttributeData) = assm.CustomAttributes
|
|
|
|
|
|
Dim vLQuery As CustomAttributeTypedArgument =
|
|
|
|
|
|
LinqAPI.DefaultFirst(Of CustomAttributeTypedArgument) <=
|
|
|
|
|
|
From attr As CustomAttributeData
|
|
|
|
|
|
In attrs
|
|
|
|
|
|
Where attr.AttributeType.Equals(GetType(AssemblyFileVersionAttribute))
|
|
|
|
|
|
Select value = attr.ConstructorArguments(Scan0)
|
|
|
|
|
|
|
|
|
|
|
|
If vLQuery.Value Is Nothing Then
|
|
|
|
|
|
Return New Version("1.0.0.0")
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return New Version(Scripting.ToString(vLQuery.Value))
|
|
|
|
|
|
End If
|
|
|
|
|
|
#Else
|
|
|
|
|
|
Throw New NotSupportedException
|
|
|
|
|
|
#End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 目标类型是不是VisualBasic之中的``Module``模块类型?
|
|
|
|
|
|
''' </summary>
|
2019-08-03 21:28:16 +08:00
|
|
|
|
''' <param name="type"></param>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<ExportAPI("Is.Module")>
|
2019-08-03 21:28:16 +08:00
|
|
|
|
<Extension> Public Function IsModule(type As Type) As Boolean
|
|
|
|
|
|
If type.Name.IndexOf("$") > -1 OrElse type.Name.IndexOf("`") > -1 Then
|
|
|
|
|
|
' 匿名类型
|
|
|
|
|
|
Return False
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Return type.IsClass
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Is type <paramref name="a"/> inherits from <paramref name="base"/> type?
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="a">继承类型继承自基本类型,具备有基本类型的所有特性</param>
|
|
|
|
|
|
''' <param name="base">基本类型</param>
|
|
|
|
|
|
''' <param name="strict">
|
|
|
|
|
|
''' + 这个参数是为了解决比较来自不同的assembly文件之中的相同类型的比较,但是这个可能会在类型转换出现一些BUG
|
|
|
|
|
|
''' + 假若不严格要求的话,那么则两种类型相等的时候也会被算作为继承关系
|
|
|
|
|
|
''' + 假若是非严格判断,那么对于泛型而言,只要基本类型也相等也会被判断为成立的继承关系,这个是为了<see cref="Activity"/>操作设计的
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' </param>
|
|
|
|
|
|
''' <param name="depth">类型继承的距离值,当这个值越大的时候,说明二者的继承越远,当进行函数重载判断的时候,选择这个距离值越小的越好</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks>假若两个类型是来自于不同的assembly文件的话,即使这两个类型是相同的对象,也会无法判断出来</remarks>
|
|
|
|
|
|
<ExportAPI("Is.InheritsFrom")>
|
|
|
|
|
|
<Extension> Public Function IsInheritsFrom(a As Type, base As Type, Optional strict As Boolean = True, Optional ByRef depth% = -1) As Boolean
|
|
|
|
|
|
Dim baseType As Type = a.BaseType
|
|
|
|
|
|
|
|
|
|
|
|
If Not strict Then
|
|
|
|
|
|
|
2019-05-09 19:16:59 +08:00
|
|
|
|
' 在这里返回结果的话,depth为-1
|
2018-08-02 20:14:48 +08:00
|
|
|
|
If a Is base Then
|
|
|
|
|
|
Return True
|
2019-07-12 21:41:13 +08:00
|
|
|
|
ElseIf depth > 16 Then
|
|
|
|
|
|
Return False
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
If a.IsGenericType AndAlso base.IsGenericType Then
|
2019-04-27 20:05:16 +08:00
|
|
|
|
Dim genericOfa As Type = a.GetGenericTypeDefinition
|
|
|
|
|
|
Dim typesOfa = a.GenericTypeArguments
|
|
|
|
|
|
Dim typesOfb = base.GenericTypeArguments
|
|
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
' 2017-3-12
|
|
|
|
|
|
' GetType(Dictionary(Of String, Double)).IsInheritsFrom(GetType(Dictionary(Of ,)))
|
|
|
|
|
|
|
2019-07-12 21:41:13 +08:00
|
|
|
|
If typesOfb.Length = 0 AndAlso genericOfa.IsInheritsFrom(base, strict, depth + 1) Then
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return True
|
|
|
|
|
|
End If
|
|
|
|
|
|
End If
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Do While Not baseType Is Nothing
|
|
|
|
|
|
depth += 1
|
|
|
|
|
|
|
|
|
|
|
|
If baseType.Equals(base) Then
|
|
|
|
|
|
Return True
|
|
|
|
|
|
ElseIf Not strict AndAlso (baseType.FullName = base.FullName) Then
|
|
|
|
|
|
Return True
|
|
|
|
|
|
Else
|
|
|
|
|
|
baseType = baseType.BaseType
|
|
|
|
|
|
End If
|
|
|
|
|
|
Loop
|
|
|
|
|
|
|
|
|
|
|
|
Return False
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 如果有<see cref="system.ComponentModel.DescriptionAttribute"/>标记,则会返回该标记的字符串数据,假若没有则只会返回类型的名称
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Function Description(Of T)() As String
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Return GetType(T).Description
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 如果有<see cref="system.ComponentModel.DescriptionAttribute"/>标记,则会返回该标记的字符串数据,假若没有则只会返回类型的名称
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<ExportAPI("Get.Description")>
|
2019-08-03 21:28:16 +08:00
|
|
|
|
<Extension> Public Function Description(type As Type) As String
|
|
|
|
|
|
Dim customAttrs As Object() = type.GetCustomAttributes(GetType(DescriptionAttribute), inherit:=False)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
If Not customAttrs.IsNullOrEmpty Then
|
|
|
|
|
|
Return CType(customAttrs(Scan0), DescriptionAttribute).Description
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Else
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Return type.Name
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets all of the can read and write access property from a type define.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="type"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
#If FRAMEWORD_CORE Then
|
|
|
|
|
|
<ExportAPI("Get.Properties")>
|
|
|
|
|
|
<Extension> Public Function GetReadWriteProperties(type As Type) As PropertyInfo()
|
|
|
|
|
|
#Else
|
|
|
|
|
|
<Extension> Public Function GetReadWriteProperties(type As System.Type) As System.Reflection.PropertyInfo()
|
|
|
|
|
|
#End If
|
|
|
|
|
|
Dim LQuery = LinqAPI.Exec(Of PropertyInfo) <=
|
|
|
|
|
|
_
|
|
|
|
|
|
From p As PropertyInfo
|
|
|
|
|
|
In type.GetProperties
|
|
|
|
|
|
Where p.CanRead AndAlso p.CanWrite
|
|
|
|
|
|
Select p
|
|
|
|
|
|
|
|
|
|
|
|
Return LQuery
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
#If NET_40 = 0 Then
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
2020-01-06 21:06:09 +08:00
|
|
|
|
''' Try convert the type specific collection data type into a generic enumerable collection data type.
|
|
|
|
|
|
''' (尝试将目标集合类型转换为通用的枚举集合类型)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' </summary>
|
2019-08-03 21:28:16 +08:00
|
|
|
|
''' <param name="type">The type specific collection data type.(特定类型的集合对象类型,当然也可以是泛型类型)</param>
|
2020-01-06 21:06:09 +08:00
|
|
|
|
''' <returns>
|
|
|
|
|
|
''' If the target data type is not a collection data type then the original data type
|
|
|
|
|
|
''' will be returns and the function displays a warning message.
|
|
|
|
|
|
''' </returns>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <remarks></remarks>
|
|
|
|
|
|
'''
|
2020-01-06 21:06:09 +08:00
|
|
|
|
<ExportAPI("Collection2GenericIEnumerable")>
|
2019-08-03 21:28:16 +08:00
|
|
|
|
<Extension> Public Function Collection2GenericIEnumerable(type As Type, Optional showDebugMsg As Boolean = True) As Type
|
|
|
|
|
|
If Array.IndexOf(type.GetInterfaces, GetType(IEnumerable)) = -1 Then
|
|
|
|
|
|
EXIT_: If showDebugMsg Then Call $"[WARN] Target type ""{type.FullName}"" is not a collection type!".__DEBUG_ECHO
|
|
|
|
|
|
Return type
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
|
2020-01-06 21:06:09 +08:00
|
|
|
|
Dim genericType As Type = GetType(IEnumerable(Of )) 'Type.GetType("System.Collections.Generic.IEnumerable")
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Dim elementType As Type = type.GetElementType
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
If elementType Is Nothing Then
|
|
|
|
|
|
Dim generics = type.GenericTypeArguments
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
If generics.IsNullOrEmpty Then
|
2018-08-02 20:14:48 +08:00
|
|
|
|
GoTo EXIT_
|
|
|
|
|
|
Else
|
2019-08-03 21:28:16 +08:00
|
|
|
|
elementType = generics(Scan0)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
genericType = genericType.MakeGenericType({elementType})
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Return genericType
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Function
|
|
|
|
|
|
#End If
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get the method reflection entry point for a anonymous lambda expression.
|
|
|
|
|
|
''' (当函数返回Nothing的时候说明目标对象不是一个函数指针)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="obj"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks></remarks>
|
|
|
|
|
|
'''
|
2020-01-06 21:06:09 +08:00
|
|
|
|
<ExportAPI("Delegate.GET_Invoke")>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Public Function GetDelegateInvokeEntryPoint(obj As Object) As MethodInfo
|
|
|
|
|
|
Dim type As Type = obj.GetType
|
|
|
|
|
|
Dim entryPoint = LinqAPI.DefaultFirst(Of MethodInfo) _
|
|
|
|
|
|
_
|
|
|
|
|
|
() <= From methodInfo As MethodInfo
|
|
|
|
|
|
In type.GetMethods
|
|
|
|
|
|
Where String.Equals(methodInfo.Name, "Invoke")
|
|
|
|
|
|
Select methodInfo
|
|
|
|
|
|
|
|
|
|
|
|
Return entryPoint
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets the full name of a method reflection meta data.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="method"></param>
|
|
|
|
|
|
''' <param name="IncludeAssembly"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<ExportAPI("Get.FullName")>
|
|
|
|
|
|
<Extension> Public Function GetFullName(method As MethodBase, Optional IncludeAssembly As Boolean = False) As String
|
|
|
|
|
|
Dim Name As String = $"{method.DeclaringType.FullName}::{method.ToString}"
|
|
|
|
|
|
If Not IncludeAssembly Then
|
|
|
|
|
|
Return Name
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return $"{method.DeclaringType.Module.Assembly.Location.ToFileURL}!{Name}"
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<ExportAPI("Get.FullName")>
|
|
|
|
|
|
<Extension> Public Function FullName(Method As MethodInfo, Optional IncludeAssembly As Boolean = False) As String
|
|
|
|
|
|
Return GetFullName(Method, IncludeAssembly)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get the specific type of custom attribute from a property.
|
|
|
|
|
|
''' If the target custom attribute is not declared on the target, then this function returns nothing.
|
|
|
|
|
|
''' (从一个属性对象中获取特定的自定义属性对象)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T">The type of the custom attribute.(自定义属性的类型)</typeparam>
|
|
|
|
|
|
''' <param name="Property">Target property object.(目标属性对象)</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks></remarks>
|
|
|
|
|
|
<Extension> Public Function GetAttribute(Of T As Attribute)([Property] As MemberInfo) As T
|
|
|
|
|
|
Dim attrType As Type = GetType(T)
|
|
|
|
|
|
Dim attrs As Object() = [Property].GetCustomAttributes(attrType, True)
|
|
|
|
|
|
|
|
|
|
|
|
If Not attrs Is Nothing AndAlso attrs.Length = 1 Then
|
|
|
|
|
|
Dim CustomAttr As T = CType(attrs(Scan0), T)
|
|
|
|
|
|
|
|
|
|
|
|
If Not CustomAttr Is Nothing Then
|
|
|
|
|
|
Return CustomAttr
|
|
|
|
|
|
End If
|
|
|
|
|
|
Else
|
|
|
|
|
|
attrs = [Property].GetCustomAttributes(attrType, False)
|
|
|
|
|
|
If Not attrs.IsNullOrEmpty Then
|
|
|
|
|
|
Return DirectCast(attrs(Scan0), T)
|
|
|
|
|
|
End If
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get the specific type of custom attribute from a property.
|
|
|
|
|
|
''' (从一个属性对象中获取特定的自定义属性对象,找不到的话,就会返回空值)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T">The type of the custom attribute.(自定义属性的类型)</typeparam>
|
|
|
|
|
|
''' <param name="Property">Target property object.(目标属性对象)</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks></remarks>
|
|
|
|
|
|
<Extension> Public Function GetAttribute(Of T As Attribute)([Property] As PropertyInfo) As T
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Dim attrs As Object() = [Property].GetCustomAttributes(GetType(T), True)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
If Not attrs Is Nothing AndAlso attrs.Length = 1 Then
|
|
|
|
|
|
Dim CustomAttr As T = CType(attrs(0), T)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
If Not CustomAttr Is Nothing Then
|
|
|
|
|
|
Return CustomAttr
|
|
|
|
|
|
End If
|
|
|
|
|
|
End If
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
#If NET_40 = 0 Then
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <param name="args">构造函数里面的参数信息</param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-03 21:28:16 +08:00
|
|
|
|
'''
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Public Function CreateObject(Of T)(args As Object(), Optional throwEx As Boolean = True, <CallerMemberName> Optional caller As String = "") As T
|
|
|
|
|
|
Return GetType(T).CreateObject(args, throwEx, caller)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function CreateObject(type As Type, args As Object(), Optional throwEx As Boolean = True, <CallerMemberName> Optional caller$ = Nothing) As Object
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Try
|
2019-08-03 21:28:16 +08:00
|
|
|
|
Dim obj As Object = Activator.CreateInstance(type, args)
|
|
|
|
|
|
|
|
|
|
|
|
If obj Is Nothing Then
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return obj
|
|
|
|
|
|
End If
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Catch ex As Exception
|
|
|
|
|
|
Dim params As String() = args _
|
2019-08-03 21:28:16 +08:00
|
|
|
|
.Select(Function(a)
|
|
|
|
|
|
Return a.GetType.FullName & " => " & GetObjectJson(a.GetType, a)
|
|
|
|
|
|
End Function) _
|
2018-08-02 20:14:48 +08:00
|
|
|
|
.ToArray
|
|
|
|
|
|
ex = New Exception(String.Join(vbCrLf, params), ex)
|
|
|
|
|
|
ex = New Exception("@" & caller, ex)
|
|
|
|
|
|
|
|
|
|
|
|
Call App.LogException(ex)
|
|
|
|
|
|
|
|
|
|
|
|
If throwEx Then
|
|
|
|
|
|
Throw ex
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Try
|
|
|
|
|
|
End Function
|
|
|
|
|
|
#End If
|
|
|
|
|
|
End Module
|