1 #Region "Microsoft.VisualBasic::96e0d4846115dc8f43e0df5a09783e90, Microsoft.VisualBasic.Core\Scripting\Runtime\CType\Narrowing.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module NarrowingReflection
35     
36     
37     '         Delegate Function
38     
39     '             Function: (+2 OverloadsGetNarrowingOperator, GetOperatorMethod
40     
41     
42     
43     ' /********************************************************************************/
44
45 #End Region
46
47 Imports System.Reflection
48 Imports System.Runtime.CompilerServices
49
50 Namespace Scripting.Runtime
51
52     Public Module NarrowingReflection
53
54         ''' <summary>
55         ''' 2070 = SpecialName
56         ''' </summary>
57         Const NarrowingOperator As BindingFlags = BindingFlags.Public Or BindingFlags.Static Or 2070
58         Const op_Explicit$ = NameOf(op_Explicit)
59
60         Public Delegate Function INarrowingOperator(Of TIn, TOut)(obj As TIn) As TOut
61
62         Public Function GetNarrowingOperator(Of TIn, TOut)() As INarrowingOperator(Of TIn, TOut)
63             Dim op As MethodInfo = CType(GetType(TIn), TypeInfo).GetOperatorMethod(Of TOut)
64
65             If op Is Nothing Then
66                 Return Nothing
67             Else
68                 Dim op_Explicit As INarrowingOperator(Of TIn, TOut) = op.CreateDelegate(GetType(INarrowingOperator(Of TIn, TOut)))
69                 Return op_Explicit
70             End If
71         End Function
72
73         ''' <summary>
74         ''' 直接使用GetMethod方法仍然会出错??如果目标类型是继承类型,基类型也有一个收缩的操作符的话,会爆出目标不明确的错误
75         ''' 
76         ''' ```vbnet
77         ''' type.GetMethod(op_Explicit, NarrowingOperator)
78         ''' ```
79         ''' </summary>
80         ''' <typeparam name="T"></typeparam>
81         ''' <param name="type"></param>
82         ''' <returns>函数找不到会返回Nothing</returns>
83         <MethodImpl(MethodImplOptions.AggressiveInlining)>
84         <Extension>
85         Private Function GetOperatorMethod(Of T)(type As TypeInfo) As MethodInfo
86             Return type.DeclaredMethods _
87                        .Where(Function(m) m.Name = op_Explicit AndAlso m.ReturnType Is GetType(T)) _
88                        .FirstOrDefault
89         End Function
90
91         <Extension>
92         Public Function GetNarrowingOperator(Of T)(type As Type) As INarrowingOperator(Of Object, T)
93             ' 函数找不到会返回Nothing
94             Dim op As MethodInfo = CType(type, TypeInfo).GetOperatorMethod(Of T)
95
96             If op Is Nothing Then
97                 Return Nothing
98             Else
99                 Dim op_Explicit As INarrowingOperator(Of Object, T) = Function(obj) DirectCast(op.Invoke(Nothing, {obj}), T)
100                 Return op_Explicit
101             End If
102         End Function
103     End Module
104 End Namespace