| 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 |