1 | #Region "Microsoft.VisualBasic::8682582cbfe5c37bf3fa8af2e775057c, Microsoft.VisualBasic.Core\Extensions\Reflection\Delegate\DataValue.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 | ' Class DataValue |
35 | ' |
36 | ' Properties: PropertyNames |
37 | ' |
38 | ' Constructor: (+1 Overloads) Sub New |
39 | ' |
40 | ' Function: GetProperty, ToString |
41 | ' |
42 | ' Sub: TestDEMO |
43 | ' |
44 | ' |
45 | ' /********************************************************************************/ |
46 | |
47 | #End Region |
48 | |
49 | Imports System.Reflection |
50 | Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel |
51 | Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel.DataFramework |
52 | Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel.SchemaMaps |
53 | Imports Microsoft.VisualBasic.Scripting.Runtime |
54 | |
55 | Namespace Emit.Delegates |
56 | |
57 | ''' <summary> |
58 | ''' .NET object collection data property value ``get/set`` helper. |
59 | ''' (将属性的<see cref="PropertyInfo.SetValue(Object, Object)"/>编译为方法调用) |
60 | ''' </summary> |
61 | Public Class DataValue(Of T) |
62 | |
63 | ReadOnly type As Type = GetType(T) |
64 | ReadOnly data As T() |
65 | ''' <summary> |
66 | ''' Using for expression tree compile to delegate by using <see cref="BindProperty(Of T)"/>, |
67 | ''' to makes the get/set invoke faster |
68 | ''' </summary> |
69 | ReadOnly properties As Dictionary(Of String, PropertyInfo) |
70 | |
71 | Public ReadOnly Property PropertyNames As String() |
72 | Get |
73 | Return properties.Values _ |
74 | .Select(Function(x) x.Name) _ |
75 | .ToArray |
76 | End Get |
77 | End Property |
78 | |
79 | Public Function GetProperty(property$) As PropertyInfo |
80 | Return properties([property]) |
81 | End Function |
82 | |
83 | ''' <summary> |
84 | ''' |
85 | ''' </summary> |
86 | ''' <param name="name$">The property name, using the ``nameof`` operator to get the property name!</param> |
87 | ''' <returns></returns> |
88 | Default Public Property Evaluate(name$) As Object |
89 | Get |
90 | Dim [property] As New BindProperty(Of DataFrameColumnAttribute)(properties(name)) |
91 | Dim vector As Array = Array.CreateInstance([property].Type, data.Length) |
92 | |
93 | For i As Integer = 0 To data.Length - 1 |
94 | Call vector.SetValue([property].__getValue(data(i)), i) |
95 | Next |
96 | |
97 | Return vector |
98 | End Get |
99 | Set(value As Object) |
100 | Dim [property] As New BindProperty(Of DataFrameColumnAttribute)(properties(name)) |
101 | Dim array As IEnumerable |
102 | |
103 | If [property].Type Is GetType(String) AndAlso value.GetType Is GetType(String) Then |
104 | array = Nothing |
105 | Else |
106 | array = TryCast(value, IEnumerable) |
107 | End If |
108 | |
109 | If value Is Nothing Then |
110 | For Each x In data |
111 | Call [property].__setValue(x, Nothing) |
112 | Next |
113 | ElseIf array Is Nothing Then ' 不是一个集合 |
114 | Dim v As Object = value |
115 | |
116 | For Each x As T In data |
117 | Call [property].__setValue(x, v) |
118 | Next |
119 | Else |
120 | Dim vector = array.As(Of Object).ToArray |
121 | |
122 | If vector.Length <> data.Length Then |
123 | Throw New InvalidExpressionException(DimNotAgree$) |
124 | End If |
125 | For i As Integer = 0 To data.Length - 1 |
126 | Call [property].__setValue(data(i), vector(i)) |
127 | Next |
128 | End If |
129 | End Set |
130 | End Property |
131 | |
132 | Const DimNotAgree$ = "Value array should have the same length as the target data array" |
133 | |
134 | 'Public Property Evaluate(Of V)(name$) As V() |
135 | ' Get |
136 | ' Dim [property] As New BindProperty(Of DataFrameColumnAttribute)(properties(name)) |
137 | ' Return data _ |
138 | ' .Select(Function(x) DirectCast([property].__getValue(x), V)) _ |
139 | ' .ToArray |
140 | ' End Get |
141 | ' Set(ParamArray value As V()) |
142 | ' Dim [property] As New BindProperty(Of DataFrameColumnAttribute)(properties(name)) |
143 | |
144 | ' If value.IsNullorEmpty Then |
145 | ' ' value array is nothing or have no data, |
146 | ' ' then means set all property value to nothing |
147 | ' For Each x In data |
148 | ' Call [property].__setValue(x, Nothing) |
149 | ' Next |
150 | ' ElseIf value.Length = 1 Then |
151 | ' ' value array only have one element, |
152 | ' ' then means set all property value to a specific value |
153 | ' Dim v As Object = value(Scan0) |
154 | ' For Each x In data |
155 | ' Call [property].__setValue(x, v) |
156 | ' Next |
157 | ' Else |
158 | ' If value.Length <> data.Length Then |
159 | ' Throw New InvalidExpressionException(DimNotAgree$) |
160 | ' End If |
161 | |
162 | ' For i As Integer = 0 To data.Length - 1 |
163 | ' Call [property].__setValue(data(i), value(i)) |
164 | ' Next |
165 | ' End If |
166 | ' End Set |
167 | 'End Property |
168 | |
169 | Sub New(src As IEnumerable(Of T)) |
170 | data = src.ToArray |
171 | properties = type.Schema(PropertyAccess.NotSure, PublicProperty, True) |
172 | End Sub |
173 | |
174 | Public Overrides Function ToString() As String |
175 | Return type.FullName |
176 | End Function |
177 | |
178 | Private Shared Sub TestDEMO() |
179 | Dim vector As NamedValue(Of String)() = {} |
180 | Dim previousData = Linq.DATA(vector).Evaluate("Value") |
181 | |
182 | Linq.DATA(vector).Evaluate("Value") = {} ' set all value property to nothing |
183 | Linq.DATA(vector).Evaluate("Value") = {"1"} ' set all value property to a specifc value "1" |
184 | Linq.DATA(vector).Evaluate("Value") = {"1", "2", "3"} |
185 | End Sub |
186 | End Class |
187 | End Namespace |