1 #Region "Microsoft.VisualBasic::cd701ddeb4c45ada871fa16dc42ffee5, 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 OverloadsSub New
39     
40     '         FunctionGetProperty, 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 StringPropertyInfo)
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