2020-01-02 19:08:37 +08:00
|
|
|
|
#Region "Microsoft.VisualBasic::55d4e45d4c2aef7ecef6295879546645, Microsoft.VisualBasic.Core\ComponentModel\DataSource\Property\DynamicProperty.vb"
|
2018-09-08 00:34:19 +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:
|
|
|
|
|
|
|
|
|
|
|
|
' Class DynamicPropertyBase
|
|
|
|
|
|
'
|
|
|
|
|
|
' Properties: MyHashCode, Properties
|
|
|
|
|
|
'
|
2020-01-02 19:08:37 +08:00
|
|
|
|
' Function: EnumerateKeys, GetEnumerator, GetItemValue, GetNames, HasProperty
|
|
|
|
|
|
' IDynamicsObject_GetItemValue, IEnumerable_GetEnumerator, ToString
|
2019-05-06 18:27:46 +08:00
|
|
|
|
'
|
2020-01-02 19:08:37 +08:00
|
|
|
|
' Sub: (+2 Overloads) Add, (+2 Overloads) SetValue
|
2018-09-08 00:34:19 +08:00
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
Imports System.Runtime.CompilerServices
|
|
|
|
|
|
Imports System.Xml.Serialization
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Language
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Linq
|
|
|
|
|
|
|
|
|
|
|
|
Namespace ComponentModel.DataSourceModel
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' This abstract object has a <see cref="propertyTable"/> dictionary keeps as
|
|
|
|
|
|
''' a dynamics property source.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
Public MustInherit Class DynamicPropertyBase(Of T)
|
|
|
|
|
|
Implements IDynamicMeta(Of T)
|
2019-04-29 18:21:51 +08:00
|
|
|
|
Implements IEnumerable(Of NamedValue(Of T))
|
2019-12-03 22:00:24 +08:00
|
|
|
|
Implements IDynamicsObject
|
2018-09-08 00:34:19 +08:00
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' The dynamics property object with specific type of value.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks>Can not serialize the dictionary object in to xml document.</remarks>
|
|
|
|
|
|
<XmlIgnore> Public Overridable Property Properties As Dictionary(Of String, T) Implements IDynamicMeta(Of T).Properties
|
|
|
|
|
|
Get
|
|
|
|
|
|
If propertyTable Is Nothing Then
|
|
|
|
|
|
propertyTable = New Dictionary(Of String, T)
|
|
|
|
|
|
End If
|
|
|
|
|
|
Return propertyTable
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As Dictionary(Of String, T))
|
|
|
|
|
|
propertyTable = value
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 动态属性表
|
|
|
|
|
|
''' </summary>
|
2019-03-07 19:00:35 +08:00
|
|
|
|
Protected propertyTable As Dictionary(Of String, T)
|
2018-09-08 00:34:19 +08:00
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets/sets item value by using property name.
|
|
|
|
|
|
''' (这个函数为安全的函数,当目标属性不存在的时候,会返回空值)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="name"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-09-30 23:21:31 +08:00
|
|
|
|
Default Public Overridable Overloads Property ItemValue(name$) As T
|
2018-09-08 00:34:19 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
If Properties.ContainsKey(name) Then
|
|
|
|
|
|
Return Properties(name)
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As T)
|
|
|
|
|
|
Properties(name) = value
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get a value package at once using a key collection,
|
|
|
|
|
|
''' if the key is not exists in the property, then its
|
|
|
|
|
|
''' correspoding value is nothing.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="keys"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads Property ItemValue(keys As IEnumerable(Of String)) As T()
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return keys.Select(Function(s) Me(s)).ToArray
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As T())
|
|
|
|
|
|
For Each key As SeqValue(Of String) In keys.SeqIterator
|
|
|
|
|
|
Me(key.value) = value(key)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
2019-04-29 18:21:51 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Add a property into the property table
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="propertyName$"></param>
|
|
|
|
|
|
''' <param name="value"></param>
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Public Sub Add(propertyName$, value As T)
|
|
|
|
|
|
If propertyTable Is Nothing Then
|
|
|
|
|
|
propertyTable = New Dictionary(Of String, T)
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Call propertyTable.Add(propertyName, value)
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
2019-12-02 22:00:05 +08:00
|
|
|
|
Public Sub SetValue(propertyName$, value As T)
|
|
|
|
|
|
If propertyTable Is Nothing Then
|
|
|
|
|
|
propertyTable = New Dictionary(Of String, T)
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
propertyTable(propertyName) = value
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
2019-11-30 11:51:07 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Public Function GetItemValue(propertyName As String) As T
|
|
|
|
|
|
Return ItemValue(propertyName)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-12-03 22:00:24 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Private Sub Add(propertyName As String, value As Object) Implements IDynamicsObject.Add
|
|
|
|
|
|
Call Add(propertyName, Conversion.CTypeDynamic(Of T)(value))
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Private Sub SetValue(propertyName As String, value As Object) Implements IDynamicsObject.SetValue
|
|
|
|
|
|
Call SetValue(propertyName, Conversion.CTypeDynamic(Of T)(value))
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Private Function IDynamicsObject_GetItemValue(propertyName As String) As Object Implements IDynamicsObject.GetItemValue
|
|
|
|
|
|
Return GetItemValue(propertyName)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-09-08 00:34:19 +08:00
|
|
|
|
''' <summary>
|
2019-12-31 23:51:59 +08:00
|
|
|
|
''' Determines whether the Dictionary contains the specified key.
|
2018-09-08 00:34:19 +08:00
|
|
|
|
''' </summary>
|
2019-12-31 23:51:59 +08:00
|
|
|
|
''' <param name="name">The key to locate in the Dictionary.</param>
|
2018-09-08 00:34:19 +08:00
|
|
|
|
''' <returns>
|
2019-12-31 23:51:59 +08:00
|
|
|
|
''' true if the Dictionary contains an element with the specified key;
|
|
|
|
|
|
''' otherwise, false.
|
2018-09-08 00:34:19 +08:00
|
|
|
|
''' </returns>
|
2019-12-31 23:51:59 +08:00
|
|
|
|
Public Function HasProperty(name As String) As Boolean Implements IDynamicsObject.HasName
|
2018-09-08 00:34:19 +08:00
|
|
|
|
If propertyTable Is Nothing Then
|
|
|
|
|
|
Return False
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return propertyTable.ContainsKey(name)
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-12-03 22:00:24 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get all keys in <see cref="Properties"/>
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Private Function GetNames() As IEnumerable(Of String) Implements IDynamicsObject.GetNames
|
|
|
|
|
|
Return Properties.Keys
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-09-08 00:34:19 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 枚举这个动态字典类型之中的所有的键名,这个函数是默认不包含有类型自有的属性名称的
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="joinProperties">是否包括属性名称,默认不包含</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Function EnumerateKeys(Optional joinProperties As Boolean = False) As String()
|
|
|
|
|
|
Dim out As New List(Of String)
|
|
|
|
|
|
|
|
|
|
|
|
If joinProperties Then
|
|
|
|
|
|
out += MyClass.GetType _
|
|
|
|
|
|
.GetProperties(PublicProperty) _
|
|
|
|
|
|
.Where(Function(p) p.GetIndexParameters.IsNullOrEmpty) _
|
|
|
|
|
|
.Select(Function(p) p.Name) _
|
|
|
|
|
|
.ToArray
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
If Not propertyTable Is Nothing Then
|
|
|
|
|
|
out += propertyTable.Keys
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Return out.Distinct.ToArray
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Overrides Function ToString() As String
|
|
|
|
|
|
Return $"{Properties.Count} Property(s)."
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Using for debugger view, this property is usually usefull for the dictionary view
|
|
|
|
|
|
''' to see if any duplicated was existed?
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Protected Overridable ReadOnly Property MyHashCode As Integer
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return GetHashCode()
|
|
|
|
|
|
End Get
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Public Shared Narrowing Operator CType(dynamic As DynamicPropertyBase(Of T)) As Func(Of String, T)
|
|
|
|
|
|
Return Function(pName$) dynamic(pName)
|
|
|
|
|
|
End Operator
|
2019-04-29 18:21:51 +08:00
|
|
|
|
|
|
|
|
|
|
Public Iterator Function GetEnumerator() As IEnumerator(Of NamedValue(Of T)) Implements IEnumerable(Of NamedValue(Of T)).GetEnumerator
|
|
|
|
|
|
For Each [property] In propertyTable
|
|
|
|
|
|
Yield New NamedValue(Of T)([property].Key, [property].Value)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
|
|
|
|
|
|
Yield GetEnumerator()
|
|
|
|
|
|
End Function
|
2018-09-08 00:34:19 +08:00
|
|
|
|
End Class
|
|
|
|
|
|
End Namespace
|