1 #Region "Microsoft.VisualBasic::c52857d123c7511ea60e7080d9558f2c, Microsoft.VisualBasic.Core\Extensions\Extensions.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 Extensions
35
36
37 Module Extensions
38
39 '     Function: [Get], [Set], Add, (+3 Overloads) AddRange, (+2 Overloads) Average
40 '               CheckDuplicated, Constrain, DataCounts, DateToString, DriverRun
41 '               ElementAtOrDefault, FirstNotEmpty, FormatTime, FuzzyMatching, GetHexInteger
42 '               (+2 OverloadsGetItem, (+2 OverloadsGetLength, IndexOf, InsertOrUpdate, Invoke
43 '               InvokeSet, Is_NA_UHandle, IsNaNImaginary, (+6 OverloadsIsNullOrEmpty, (+4 Overloads) Join
44 '               (+2 Overloads) JoinBy, Keys, KeysJson, Log2, (+2 OverloadsLongSeq
45 '               MatrixToUltraLargeVector, MatrixTranspose, MatrixTransposeIgnoredDimensionAgreement, MD5, ModifyValue
46 '               NormalizeXMLString, NotNull, (+2 OverloadsOffset, ParseDateTime, Range
47 '               Remove, RemoveDuplicates, RemoveFirst, (+2 Overloads) RemoveLast, RunDriver
48 '               SaveAsTabularMapping, Second, SelectFile, SeqRandom, (+2 Overloads) Sequence
49 '               (+2 OverloadsSetValue, (+11 Overloads) ShadowCopy, Shell, Shuffles, Split
50 '               SplitIterator, (+2 Overloads) SplitMV, StdError, TakeRandomly, Takes
51 '               ToBoolean, ToDictionary, ToNormalizedPathString, ToStringArray, ToVector
52 '               (+3 Overloads) TrimNull, (+2 OverloadsTryGetValue, Unlist, WriteAddress
53
54 '     Sub: Add, FillBlank, Removes, (+2 Overloads) SendMessage, Swap
55 '          SwapItem, SwapWith
56
57
58
59 ' /********************************************************************************/
60
61 #End Region
62
63 Imports System.Collections.ObjectModel
64 Imports System.Drawing
65 Imports System.Globalization
66 Imports System.Reflection
67 Imports System.Runtime.CompilerServices
68 Imports System.Text
69 Imports Microsoft.VisualBasic.ApplicationServices
70 Imports Microsoft.VisualBasic.CommandLine
71 Imports Microsoft.VisualBasic.CommandLine.Reflection
72 Imports Microsoft.VisualBasic.ComponentModel
73 Imports Microsoft.VisualBasic.ComponentModel.Collection
74 Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic
75 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
76 Imports Microsoft.VisualBasic.ComponentModel.Ranges.Model
77 Imports Microsoft.VisualBasic.Language
78 Imports Microsoft.VisualBasic.Language.Vectorization
79 Imports Microsoft.VisualBasic.Linq
80 Imports Microsoft.VisualBasic.Linq.Extensions
81 Imports Microsoft.VisualBasic.Parallel
82 Imports Microsoft.VisualBasic.Scripting.MetaData
83 Imports Microsoft.VisualBasic.SecurityString
84 Imports Microsoft.VisualBasic.Serialization.JSON
85 Imports Microsoft.VisualBasic.Terminal
86 Imports Microsoft.VisualBasic.Text
87 Imports Microsoft.VisualBasic.Text.Levenshtein
88 Imports Microsoft.VisualBasic.Text.Similarity
89 Imports sys = System.Math
90 Imports v = System.Array
91
92 #Const FRAMEWORD_CORE = 1
93 #Const Yes = 1
94
95 #If FRAMEWORD_CORE = Yes Then
96
97 ''' <summary>
98 ''' Common extension methods library for convenient the programming job.
99 ''' </summary>
100 ''' <remarks></remarks>
101 <Package("Framework.Extensions",
102                     Description:="The common extension methods module in this Microsoft.VisualBasic program assembly." &
103                                  "Common extension methods library for convenient the programming job.",
104                     Publisher:="xie.guigang@gmail.com",
105                     Revision:=8655,
106                     Url:="http://github.com/xieguigang/sciBASIC#")>
107 <Extension> Public Module Extensions
108 #Else
109
110 ''' <summary>
111 ''' Common extension methods library for convenient the programming job.
112 ''' </summary>
113 ''' <remarks></remarks>
114 Public Module Extensions
115 #End If
116
117     <MethodImpl(MethodImplOptions.AggressiveInlining)>
118     <Extension>
119     Public Function Average(range As DoubleRange) As Double
120         Return {range.Min, range.Max}.Average
121     End Function
122
123     ''' <summary>
124     ''' Create the numeric range from a numeric value collection
125     ''' </summary>
126     ''' <param name="data"></param>
127     ''' <returns></returns>
128     <Extension>
129     <MethodImpl(MethodImplOptions.AggressiveInlining)>
130     Public Function Range(data As IEnumerable(Of Double), Optional scale# = 1) As DoubleRange
131         Return New DoubleRange(data) * scale
132     End Function
133
134     ''' <summary>
135     ''' ``Math.Log(x, newBase:=2)``
136     ''' </summary>
137     ''' <param name="x#"></param>
138     ''' <returns></returns>
139     ''' 
140     <MethodImpl(MethodImplOptions.AggressiveInlining)>
141     <Extension> Public Function Log2(x#) As Double
142         Return sys.Log(x, newBase:=2)
143     End Function
144
145     ''' <summary>
146     ''' 将16进制的数字转换为10进制数
147     ''' </summary>
148     ''' <param name="hex$"></param>
149     ''' <returns></returns>
150     ''' <remarks>
151     ''' 因为直接使用vb的<see cref="Val"/>函数转换,在Linux上面可能会出错,所以需要在这里用.NET自己的方法来转换
152     ''' </remarks>
153     ''' 
154     <MethodImpl(MethodImplOptions.AggressiveInlining)>
155     Public Function GetHexInteger(hex$) As Integer
156         Dim num% = Integer.Parse(hex, NumberStyles.HexNumber)
157         Return num
158     End Function
159
160     ''' <summary>
161     ''' Save as a tsv file, with data format like: 
162     ''' 
163     ''' ```
164     ''' <see cref="NamedValue(Of String).Name"/>\t<see cref="NamedValue(Of String).Value"/>\t<see cref="NamedValue(Of String).Description"/>
165     ''' ```
166     ''' </summary>
167     ''' <param name="source"></param>
168     ''' <param name="path$"></param>
169     ''' <param name="encoding"></param>
170     ''' <returns></returns>
171     <Extension>
172     Public Function SaveAsTabularMapping(source As IEnumerable(Of NamedValue(Of String)),
173                                          path$,
174                                          Optional saveDescrib As Boolean = False,
175                                          Optional saveHeaders$() = Nothing,
176                                          Optional encoding As Encodings = Encodings.ASCII) As Boolean
177         Dim content = source _
178             .Select(Function(row)
179                         With row
180                             If saveDescrib Then
181                                 Return $"{ .Name}{ASCII.TAB}{ .Value}{ASCII.TAB}{ .Description}"
182                             Else
183                                 Return $"{ .Name}{ASCII.TAB}{ .Value}"
184                             End If
185                         End With
186                     End Function)
187
188         If saveHeaders.IsNullOrEmpty Then
189             Return content.SaveTo(path, encoding.CodePage)
190         Else
191             Return {saveHeaders.JoinBy(ASCII.TAB)}.JoinIterates(content).SaveTo(path, encoding.CodePage)
192         End If
193     End Function
194
195     ''' <summary>
196     ''' ``days, hh:mm:ss.ms``
197     ''' </summary>
198     ''' <param name="t"></param>
199     ''' <returns></returns>
200     ''' 
201     <MethodImpl(MethodImplOptions.AggressiveInlining)>
202     <Extension>
203     Public Function FormatTime(t As TimeSpan) As String
204         With t
205             Return $"{ZeroFill(.Days, 2)}, {ZeroFill(.Hours, 2)}:{ZeroFill(.Minutes, 2)}:{ZeroFill(.Seconds, 2)}.{ .Milliseconds}"
206         End With
207     End Function
208
209     <Extension>
210     Public Function Average(data As IEnumerable(Of TimeSpan)) As TimeSpan
211         Dim avg# = data.Select(Function(x) x.TotalMilliseconds).Average
212         Return TimeSpan.FromMilliseconds(avg)
213     End Function
214
215     ''' <summary>
216     ''' Returns all of the keys in a dictionary in json format
217     ''' </summary>
218     ''' <typeparam name="V"></typeparam>
219     ''' <param name="d"></param>
220     ''' <returns></returns>
221     ''' 
222     <MethodImpl(MethodImplOptions.AggressiveInlining)>
223     <Extension>
224     Public Function KeysJson(Of V)(d As Dictionary(Of String, V)) As String
225         Return d.Keys.ToArray.GetJson
226     End Function
227
228     ''' <summary>
229     ''' Returns the first not nothing object.
230     ''' </summary>
231     ''' <typeparam name="T">
232     ''' Due to the reason of value type is always not nothing, so that this generic type constrain as Class reference type.
233     ''' </typeparam>
234     ''' <param name="args"></param>
235     ''' <returns></returns>
236     Public Function NotNull(Of T As Class)(ParamArray args As T()) As T
237         If args.IsNullOrEmpty Then
238             Return Nothing
239         Else
240             For Each x In args
241                 If Not x Is Nothing Then
242                     Return x
243                 End If
244             Next
245         End If
246
247         Return Nothing
248     End Function
249
250     ''' <summary>
251     ''' Get target string's md5 hash code
252     ''' </summary>
253     ''' <param name="s$"></param>
254     ''' <returns></returns>
255     <MethodImpl(MethodImplOptions.AggressiveInlining)>
256     <Extension> Public Function MD5(s$) As String
257         Return s.GetMd5Hash
258     End Function
259
260     ''' <summary>
261     ''' Returns the first not null or empty string.
262     ''' </summary>
263     ''' <param name="args"></param>
264     ''' <returns></returns>
265     Public Function FirstNotEmpty(ParamArray args As String()) As String
266         If args.IsNullOrEmpty Then
267             Return ""
268         Else
269             For Each s As String In args
270                 If Not String.IsNullOrEmpty(s) Then
271                     Return s
272                 End If
273             Next
274         End If
275
276         Return ""
277     End Function
278
279     ''' <summary>
280     ''' Returns the second element in the source collection, if the collection 
281     ''' is nothing or elements count not enough, then will returns nothing if 
282     ''' the <paramref name="suppressError"/> option was opend, otherwise this 
283     ''' function will throw exception.
284     ''' </summary>
285     ''' <typeparam name="T"></typeparam>
286     ''' <param name="source"></param>
287     ''' <returns></returns>
288     <Extension> Public Function Second(Of T)(source As IEnumerable(Of T), Optional suppressError As Boolean = FalseOptional [default] As T = NothingAs T
289         For Each x As SeqValue(Of T) In source.SeqIterator
290             If x.i = 1 Then
291                 Return x.value
292             End If
293         Next
294
295         If Not suppressError Then
296             Throw New IndexOutOfRangeException
297         Else
298             Return [default]
299         End If
300     End Function
301
302     <Extension> Public Function Add(Of T As INamedValue)(ByRef table As Dictionary(Of String, T), obj As T) As Dictionary(Of String, T)
303         If table Is Nothing Then
304             table = New Dictionary(Of String, T)
305         End If
306         If table.ContainsKey(obj.Key) Then
307             Throw New Exception($"[{obj.Key}] was duplicated in the dictionary!")
308         Else
309             Call table.Add(obj.Key, obj)
310         End If
311
312         Return table
313     End Function
314
315     <Extension>
316     Public Function IndexOf(Of T)(source As Queue(Of T), x As T) As Integer
317         If source.IsNullOrEmpty Then
318             Return -1
319         Else
320             Return source.AsList.IndexOf(x)
321         End If
322     End Function
323
324     ''' <summary>
325     ''' Gets all keys value from the target <see cref="KeyValuePair"/> collection.
326     ''' </summary>
327     ''' <typeparam name="T1"></typeparam>
328     ''' <typeparam name="T2"></typeparam>
329     ''' <param name="source"></param>
330     ''' <returns></returns>
331     ''' 
332     <MethodImpl(MethodImplOptions.AggressiveInlining)>
333     <Extension> Public Function Keys(Of T1, T2)(source As IEnumerable(Of KeyValuePair(Of T1, T2))) As T1()
334         Return source.Select(Function(x) x.Key).ToArray
335     End Function
336
337     ''' <summary>
338     ''' Adds the elements of the specified collection to the end of the List`1.
339     ''' (会自动跳过空集合,这个方法是安全的)
340     ''' </summary>
341     ''' <typeparam name="T"></typeparam>
342     ''' <param name="list"></param>
343     ''' <param name="value">The collection whose elements should be added to the end of the List`1.</param>
344     <Extension> Public Sub Add(Of T)(ByRef list As List(Of T), ParamArray value As T())
345         If value.IsNullOrEmpty Then
346             Return
347         Else
348             Call list.AddRange(value)
349         End If
350     End Sub
351
352     ''' <summary>
353     ''' Safe get the specific index element from the target collection, is the index value invalid, then default value will be return.
354     ''' (假若下标越界的话会返回默认值)
355     ''' </summary>
356     ''' <typeparam name="T"></typeparam>
357     ''' <param name="array"></param>
358     ''' <param name="index"></param>
359     ''' <param name="[default]">Default value for invalid index is nothing.</param>
360     ''' <returns></returns>
361     <Extension> Public Function [Get](Of T)(array As IEnumerable(Of T), index As IntegerOptional [default] As T = NothingAs T
362         If array Is Nothing Then
363             Return [default]
364         End If
365
366         If index < 0 OrElse index >= array.Count Then
367             Return [default]
368         End If
369
370         Dim value As T = array(index)
371         Return value
372     End Function
373
374     ''' <summary>
375     ''' This is a safely method for gets the value in a array, if the index was outside of the boundary, then the default value will be return.
376     ''' (假若下标越界的话会返回默认值)
377     ''' </summary>
378     ''' <typeparam name="T"></typeparam>
379     ''' <param name="array"></param>
380     ''' <param name="index"></param>
381     ''' <param name="[default]">Default value for return when the array object is nothing or index outside of the boundary.</param>
382     ''' <returns></returns>
383     <Extension> Public Function ElementAtOrDefault(Of T)(array As T(), index As IntegerOptional [default] As T = NothingAs T
384         If array.IsNullOrEmpty Then
385             Return [default]
386         End If
387
388         If index < 0 OrElse index >= array.Length Then
389             Return [default]
390         End If
391
392         Dim value As T = array(index)
393         Return value
394     End Function
395
396     <Extension> Public Function [Set](Of T)(ByRef array As T(), index As Integer, value As T) As T()
397         If index < 0 Then
398             Return array
399         End If
400
401         If array.Length - 1 >= index Then
402             array(index) = value
403         Else
404             Dim copy As T() = New T(index) {}
405             Call System.Array.ConstrainedCopy(array, Scan0, copy, Scan0, array.Length)
406             copy(index) = value
407             array = copy
408         End If
409
410         Return array
411     End Function
412
413 #Region ""
414
415     <ExportAPI("SendMessage")>
416     <Extension> Public Sub SendMessage(host As System.Net.IPEndPoint, request As StringCallback As Action(Of String))
417         Dim client As New Net.AsynInvoke(host)
418         Call New Threading.Thread(Sub() Callback(client.SendMessage(request))).Start()
419     End Sub
420
421     <ExportAPI("SendMessage")>
422     <Extension> Public Sub SendMessage(host As Net.IPEndPoint, request As StringCallback As Action(Of String))
423         Call host.GetIPEndPoint.SendMessage(request, Callback)
424     End Sub
425
426 #End Region
427
428     ''' <summary>
429     ''' Constrain the inherits class type into the base type.
430     ''' (基类集合与继承类的集合约束)
431     ''' </summary>
432     ''' <typeparam name="T">继承类向基类进行约束</typeparam>
433     ''' <typeparam name="Tbase">基类</typeparam>
434     ''' <returns></returns>
435     Public Function Constrain(Of Tbase As Class, T As Tbase)(source As IEnumerable(Of T)) As Tbase()
436         If source Is Nothing Then
437             Return New Tbase() {}
438         End If
439
440         Dim array As T() = source.ToArray
441         Dim out As Tbase() = New Tbase(array.Length - 1) {}
442
443         For i As Integer = 0 To out.Length - 1
444             out(i) = source(i)
445         Next
446
447         Return out
448     End Function
449
450     ''' <summary>
451     ''' 0 -> False
452     ''' 1 -> True
453     ''' </summary>
454     ''' <param name="b"></param>
455     ''' <returns></returns>
456     <Extension> Public Function ToBoolean(b As LongAs Boolean
457         If b = 0 Then
458             Return False
459         Else
460             Return True
461         End If
462     End Function
463
464     ''' <summary>
465     ''' 假若不存在目标键名,则返回空值,默认值为空值
466     ''' </summary>
467     ''' <typeparam name="TKey"></typeparam>
468     ''' <typeparam name="TValue"></typeparam>
469     ''' <param name="table"></param>
470     ''' <param name="index"></param>
471     ''' <param name="[default]"></param>
472     ''' <returns></returns>
473     <Extension> Public Function TryGetValue(Of TKey, TValue)(table As Dictionary(Of TKey, TValue),
474                                                              index As TKey,
475                                                              Optional [default] As TValue = Nothing,
476                                                              <CallerMemberName> Optional trace$ = NothingAs TValue
477         ' 表示空的,或者键名是空的,都意味着键名不存在与表之中
478         ' 直接返回默认值
479         If table Is Nothing Then
480 #If DEBUG Then
481             Call PrintException("Hash_table is nothing!")
482 #End If
483             Return [default]
484         ElseIf index Is Nothing Then
485 #If DEBUG Then
486             Call PrintException("Index key is nothing!")
487 #End If
488             Return [default]
489         ElseIf Not table.ContainsKey(index) Then
490 #If DEBUG Then
491             Call PrintException($"missing_index:={Scripting.ToString(index)}!", trace)
492 #End If
493             Return [default]
494         End If
495
496         Return table(index)
497     End Function
498
499     <Extension> Public Function TryGetValue(Of TKey, TValue, TProp)(hash As Dictionary(Of TKey, TValue), Index As TKey, prop As StringAs TProp
500         If hash Is Nothing Then
501             Return Nothing
502         End If
503
504         If Not hash.ContainsKey(Index) Then
505             Return Nothing
506         End If
507
508         Dim obj As TValue = hash(Index)
509         Dim propertyInfo As PropertyInfo = obj.GetType.GetProperty(prop)
510
511         If propertyInfo Is Nothing Then
512             Return Nothing
513         End If
514
515         Dim value As Object = propertyInfo.GetValue(obj, Nothing)
516         Return DirectCast(value, TProp)
517     End Function
518
519     <Extension> Public Function AddRange(Of TKey, TValue)(ByRef table As Dictionary(Of TKey, TValue), data As IEnumerable(Of KeyValuePair(Of TKey, TValue))) As Dictionary(Of TKey, TValue)
520         If data Is Nothing Then
521             Return table
522         End If
523
524         For Each obj In data
525             Call table.Add(obj.Key, obj.Value)
526         Next
527         Return table
528     End Function
529
530     ''' <summary>
531     ''' 对Xml文件之中的特殊字符进行转义处理
532     ''' </summary>
533     ''' <param name="str"></param>
534     ''' <returns></returns>
535     ''' <remarks></remarks>
536     <Extension> Public Function NormalizeXMLString(str As StringAs String
537         Dim sBuilder As StringBuilder = New StringBuilder(str)
538
539         Call sBuilder.Replace("&""&amp;")
540         Call sBuilder.Replace("""""&quot;")
541         Call sBuilder.Replace("×""&times;")
542         Call sBuilder.Replace("÷""&divide;")
543         Call sBuilder.Replace("<""&lt;")
544         Call sBuilder.Replace(">""&gt;")
545
546         Return sBuilder.ToString
547     End Function
548
549     ''' <summary>
550     ''' Format the datetime value in the format of yy/mm/dd hh:min
551     ''' </summary>
552     ''' <param name="dat"></param>
553     ''' <returns></returns>
554     <ExportAPI("Date.ToString"Info:="Format the datetime value in the format of yy/mm/dd hh:min")>
555     <Extension> Public Function DateToString(dat As DateAs String
556         Dim yy = dat.Year
557         Dim mm As String = dat.Month.FormatZero
558         Dim dd As String = dat.Day.FormatZero
559         Dim hh As String = dat.Hour.FormatZero
560         Dim mmin As String = dat.Minute.FormatZero
561
562         Return $"{yy}/{mm}/{dd} {hh}:{mmin}"
563     End Function
564
565     <ExportAPI("Date.ToNormalizedPathString")>
566     <Extension> Public Function ToNormalizedPathString(dat As DateAs String
567         Dim yy = dat.Year
568         Dim mm As String = dat.Month.FormatZero
569         Dim dd As String = dat.Day.FormatZero
570         Dim hh As String = dat.Hour.FormatZero
571         Dim mmin As String = dat.Minute.FormatZero
572
573         Return String.Format("{0}-{1}-{2} {3}.{4}", yy, mm, dd, hh, mmin)
574     End Function
575
576     ''' <summary>
577     ''' Data partitioning function.
578     ''' (将目标集合之中的数据按照<paramref name="parTokens"></paramref>参数分配到子集合之中,
579     ''' 这个函数之中不能够使用并行化Linq拓展,以保证元素之间的相互原有的顺序,
580     ''' 每一个子集和之中的元素数量为<paramref name="parTokens"/>)
581     ''' </summary>
582     ''' <typeparam name="T"></typeparam>
583     ''' <param name="source"></param>
584     ''' <param name="parTokens">每一个子集合之中的元素的数目</param>
585     ''' <returns></returns>
586     ''' <remarks></remarks>
587     <MethodImpl(MethodImplOptions.AggressiveInlining)>
588     <Extension> Public Function Split(Of T)(source As IEnumerable(Of T), parTokens As IntegerOptional echo As Boolean = TrueAs T()()
589         Return source.SplitIterator(parTokens, echo).ToArray
590     End Function
591
592     ''' <summary>
593     ''' Performance the partitioning operation on the input sequence.
594     ''' (请注意,这个函数只适用于数量较少的序列。对所输入的序列进行分区操作,<paramref name="parTokens"/>函数参数是每一个分区里面的元素的数量)
595     ''' </summary>
596     ''' <typeparam name="T"></typeparam>
597     ''' <param name="source"></param>
598     ''' <param name="parTokens"></param>
599     ''' <returns></returns>
600     <Extension>
601     Public Iterator Function SplitIterator(Of T)(source As IEnumerable(Of T), parTokens As IntegerOptional echo As Boolean = TrueAs IEnumerable(Of T())
602         Dim buf As T() = source.SafeQuery.ToArray
603         Dim n As Integer = buf.Length
604         Dim count As Integer
605
606         If echo AndAlso n >= 50000 Then
607             Call $"Start large data set(size:={n}) partitioning...".__DEBUG_ECHO
608         End If
609
610         For i As Integer = 0 To n - 1 Step parTokens
611             Dim buffer As T()
612
613             If n - i >= parTokens Then
614                 buffer = New T(parTokens - 1) {}
615             Else
616                 buffer = New T(n - i - 1) {}
617             End If
618
619             Call Array.ConstrainedCopy(buf, i, buffer, Scan0, buffer.Length)
620             Yield buffer
621
622             count += 1
623         Next
624
625         If echo AndAlso n >= 50000 Then
626             Call $"Large data set data partitioning(partitions:={count}) jobs done!".__DEBUG_ECHO
627         End If
628     End Function
629
630     ''' <summary>
631     ''' Merge two type specific collection.(函数会忽略掉空的集合,函数会构建一个新的集合,原有的集合不受影响)
632     ''' </summary>
633     ''' <typeparam name="T"></typeparam>
634     ''' <param name="source"></param>
635     ''' <param name="target"></param>
636     ''' <returns></returns>
637     <Extension> Public Function Join(Of T)(source As IEnumerable(Of T), target As IEnumerable(Of T)) As List(Of T)
638         Dim srcList As List(Of T) = If(source Is NothingNew List(Of T), source.AsList)
639         If Not target Is Nothing Then
640             Call srcList.AddRange(target)
641         End If
642         Return srcList
643     End Function
644
645     <MethodImpl(MethodImplOptions.AggressiveInlining)>
646     <Extension> Public Function Join(Of T)(source As IEnumerable(Of T), ParamArray data As T()) As List(Of T)
647         Return source.Join(target:=data)
648     End Function
649
650     ''' <summary>
651     ''' This is a safe function: if the source string collection is nothing, then whistle function will returns a empty string instead of throw exception. 
652     ''' (<see cref="String.Join"/>,这是一个安全的函数,当数组为空的时候回返回空字符串)
653     ''' </summary>
654     ''' <param name="tokens"></param>
655     ''' <param name="delimiter"></param>
656     ''' <returns></returns>
657     <Extension> Public Function JoinBy(tokens As IEnumerable(Of String), delimiter$) As String
658         If tokens Is Nothing Then
659             Return ""
660         End If
661         Return String.Join(delimiter, tokens.ToArray)
662     End Function
663
664     ''' <summary>
665     ''' <see cref="String.Join"/>,这是一个安全的函数,当数组为空的时候回返回空字符串
666     ''' </summary>
667     ''' <param name="values"></param>
668     ''' <param name="delimiter"></param>
669     ''' <returns></returns>
670     <Extension> Public Function JoinBy(values As IEnumerable(Of Integer), delimiter$) As String
671         If values Is Nothing Then
672             Return ""
673         End If
674         Return String.Join(delimiter, values.Select(Function(n) CStr(n)).ToArray)
675     End Function
676
677     <Extension> Public Function Join(Of T)(source As IEnumerable(Of T), data As T) As List(Of T)
678         Return source.Join({data})
679     End Function
680
681     ''' <summary>
682     ''' ``X, ....``
683     ''' 
684     ''' (这个函数是一个安全的函数,当<paramref name="collection"/>为空值的时候回忽略掉<paramref name="collection"/>,
685     ''' 只返回包含有一个<paramref name="obj"/>元素的列表)
686     ''' </summary>
687     ''' <typeparam name="T"></typeparam>
688     ''' <param name="obj"></param>
689     ''' <param name="collection"></param>
690     ''' <returns></returns>
691     <Extension> Public Function Join(Of T)(obj As T, collection As IEnumerable(Of T)) As List(Of T)
692         With New List(Of T) From {obj}
693             If Not collection Is Nothing Then
694                 Call .AddRange(collection)
695             End If
696
697             Return .ByRef
698         End With
699     End Function
700
701 #If FRAMEWORD_CORE Then
702     ''' <summary>
703     ''' Show open file dialog and return the selected file path.
704     ''' </summary>
705     ''' <param name="ext$"></param>
706     ''' <returns></returns>
707     <ExportAPI("File.Select",
708                Info:="Open the file open dialog to gets the file")>
709     Public Function SelectFile(Optional ext$ = "*.*"Optional title$ = NothingAs String
710         Dim mime$ = ext.GetMIMEDescrib.Details
711
712         Using Open As New OpenFileDialog With {
713             .Filter = $"{ext}|{ext}",
714             .Title = If(title.StringEmpty, $"Open {mime}", title)
715         }
716             If Open.ShowDialog = DialogResult.OK Then
717                 Return Open.FileName
718             Else
719                 Return Nothing
720             End If
721         End Using
722     End Function
723 #End If
724
725     ''' <summary>
726     ''' 本方法会执行外部命令并等待其执行完毕,函数返回状态值
727     ''' </summary>
728     ''' <param name="Process"></param>
729     ''' <returns></returns>
730     ''' <remarks></remarks>
731     '''
732     <ExportAPI("Invoke"Info:="Invoke a folked system process object to execute a parallel task.")>
733     <Extension> Public Function Invoke(Process As Process) As Integer
734         Call Process.Start()
735         Call Process.WaitForExit()
736         Return Process.ExitCode
737     End Function
738
739 #If FRAMEWORD_CORE Then
740     ''' <summary>
741     ''' 非线程的方式启动,当前线程会被阻塞在这里直到运行完毕
742     ''' </summary>
743     ''' <param name="driver"></param>
744     ''' <returns></returns>
745     <ExportAPI("Run"Info:="Running the object model driver, the target object should implement the driver interface.")>
746     Public Function RunDriver(driver As ITaskDriver) As Integer
747         Return driver.Run
748     End Function
749
750     ''' <summary>
751     ''' Run the driver in a new thread, NOTE: from this extension function calls, then run thread is already be started, 
752     ''' so that no needs of calling the method <see cref="Threading.Thread.Start()"/> again.
753     ''' (使用线程的方式启动,在函数调用之后,线程是已经启动了的,所以不需要再次调用<see cref="Threading.Thread.Start()"/>方法了)
754     ''' </summary>
755     ''' <param name="driver">The object which is implements the interface <see cref="ITaskDriver"/></param>
756     <ExportAPI("Run"Info:="Running the object model driver, the target object should implement the driver interface.")>
757     <Extension>
758     Public Function DriverRun(driver As ITaskDriver) As Threading.Thread
759         Return Parallel.RunTask(AddressOf driver.Run)
760     End Function
761 #End If
762
763     ''' <summary>
764     ''' Gets the element counts in the target data collection, if the collection object is nothing or empty
765     ''' then this function will returns ZERO, others returns Collection.Count.(返回一个数据集合之中的元素的数目,
766     ''' 假若这个集合是空值或者空的,则返回0,其他情况则返回Count拓展函数的结果)
767     ''' </summary>
768     ''' <typeparam name="T"></typeparam>
769     ''' <param name="collection"></param>
770     ''' <returns></returns>
771     ''' <remarks></remarks>
772     <Extension> Public Function DataCounts(Of T)(collection As IEnumerable(Of T)) As Integer
773         If collection Is Nothing Then
774             Return 0
775         ElseIf TypeOf collection Is T() Then
776             Return DirectCast(collection, T()).Length
777         ElseIf collection.GetType.IsInheritsFrom(GetType(System.Collections.Generic.List(Of T))) Then
778             Return DirectCast(collection, System.Collections.Generic.List(Of T)).Count
779         Else
780             Return Enumerable.Count(collection)
781         End If
782     End Function
783
784     ''' <summary>
785     ''' All of the number value in the target array offset a integer value.
786     ''' </summary>
787     ''' <param name="array"></param>
788     ''' <param name="intOffset"></param>
789     ''' <returns></returns>
790     <ExportAPI("OffSet")>
791     <Extension> Public Function Offset(ByRef array As Integer(), intOffset As IntegerAs Integer()
792         For i As Integer = 0 To array.Length - 1
793             array(i) = array(i) + intOffset
794         Next
795         Return array
796     End Function
797
798     ''' <summary>
799     ''' All of the number value in the target array offset a integer value.
800     ''' </summary>
801     ''' <param name="array"></param>
802     ''' <param name="intOffset"></param>
803     ''' <returns></returns>
804     <ExportAPI("OffSet")>
805     <Extension> Public Function Offset(ByRef array As Long(), intOffset As IntegerAs Long()
806         For i As Integer = 0 To array.Length - 1
807             array(i) = array(i) + intOffset
808         Next
809         Return array
810     End Function
811
812     ''' <summary>
813     ''' Parsing the dat value from the expression text, if any exception happend, a null date value will returned.
814     ''' (空字符串会返回空的日期)
815     ''' </summary>
816     ''' <param name="s"></param>
817     ''' <returns></returns>
818     '''
819     <ExportAPI("Date.Parse")>
820     <Extension> Public Function ParseDateTime(s As StringAs Date
821         If String.IsNullOrEmpty(s) Then
822             Return New Date
823         Else
824             Return DateTime.Parse(s)
825         End If
826     End Function
827
828 #Region ""
829
830     <Extension> Public Function InvokeSet(Of T As Class, Tvalue)(obj As T, [Property] As PropertyInfo, value As Tvalue) As T
831         Call [Property].SetValue(obj, value, Nothing)
832         Return obj
833     End Function
834
835     ''' <summary>
836     ''' Value assignment to the target variable.(将<paramref name="value"/>参数里面的值赋值给<paramref name="var"/>参数然后返回<paramref name="value"/>)
837     ''' </summary>
838     ''' <typeparam name="T"></typeparam>
839     ''' <param name="var"></param>
840     ''' <param name="value"></param>
841     ''' <returns></returns>
842     ''' <remarks></remarks>
843     ''' 
844     <MethodImpl(MethodImplOptions.AggressiveInlining)>
845     <Extension> Public Function SetValue(Of T)(ByRef var As T, value As T) As T
846         var = value
847         Return value
848     End Function
849
850     <MethodImpl(MethodImplOptions.AggressiveInlining)>
851     <Extension>
852     Public Function SetValue(Of T)(ByRef var As T, value As Func(Of T, T)) As T
853         var = value(arg:=var)
854         Return var
855     End Function
856
857     ''' <summary>
858     ''' Copy the source value directly to the target variable and then return the source value.
859     ''' </summary>
860     ''' <typeparam name="T"></typeparam>
861     ''' <param name="source"></param>
862     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T) As T
863         arg1 = source
864         arg2 = source
865         Return source
866     End Function
867
868     ''' <summary>
869     ''' Copy the source value directly to the target variable and then return the source value.
870     ''' </summary>
871     ''' <typeparam name="T"></typeparam>
872     ''' <param name="source"></param>
873     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T) As T
874         arg1 = source
875         arg2 = source
876         arg3 = source
877         Return source
878     End Function
879     ''' <summary>
880     ''' Copy the source value directly to the target variable and then return the source value.
881     ''' </summary>
882     ''' <typeparam name="T"></typeparam>
883     ''' <param name="source"></param>
884     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T) As T
885         arg1 = source
886         arg2 = source
887         arg3 = source
888         arg4 = source
889         Return source
890     End Function
891     ''' <summary>
892     ''' Copy the source value directly to the target variable and then return the source value.
893     ''' </summary>
894     ''' <typeparam name="T"></typeparam>
895     ''' <param name="source"></param>
896     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T) As T
897         arg1 = source
898         arg2 = source
899         arg3 = source
900         arg4 = source
901         arg5 = source
902         Return source
903     End Function
904     ''' <summary>
905     ''' Copy the source value directly to the target variable and then return the source value.
906     ''' </summary>
907     ''' <typeparam name="T"></typeparam>
908     ''' <param name="source"></param>
909     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T) As T
910         arg1 = source
911         arg2 = source
912         arg3 = source
913         arg4 = source
914         arg5 = source
915         arg6 = source
916         Return source
917     End Function
918     ''' <summary>
919     ''' Copy the source value directly to the target variable and then return the source value.
920     ''' </summary>
921     ''' <typeparam name="T"></typeparam>
922     ''' <param name="source"></param>
923     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T, ByRef arg7 As T) As T
924         arg1 = source
925         arg2 = source
926         arg3 = source
927         arg4 = source
928         arg5 = source
929         arg6 = source
930         arg7 = source
931         Return source
932     End Function
933     ''' <summary>
934     ''' Copy the source value directly to the target variable and then return the source value.
935     ''' </summary>
936     ''' <typeparam name="T"></typeparam>
937     ''' <param name="source"></param>
938     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T, ByRef arg7 As T, ByRef arg8 As T) As T
939         arg1 = source
940         arg2 = source
941         arg3 = source
942         arg4 = source
943         arg5 = source
944         arg6 = source
945         arg7 = source
946         arg8 = source
947         Return source
948     End Function
949     ''' <summary>
950     ''' Copy the source value directly to the target variable and then return the source value.
951     ''' </summary>
952     ''' <typeparam name="T"></typeparam>
953     ''' <param name="source"></param>
954     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T, ByRef arg7 As T, ByRef arg8 As T, ByRef arg9 As T) As T
955         arg1 = source
956         arg2 = source
957         arg3 = source
958         arg4 = source
959         arg5 = source
960         arg6 = source
961         arg7 = source
962         arg8 = source
963         arg9 = source
964         Return source
965     End Function
966     ''' <summary>
967     ''' Copy the source value directly to the target variable and then return the source value.
968     ''' </summary>
969     ''' <typeparam name="T"></typeparam>
970     ''' <param name="source"></param>
971     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T, ByRef arg7 As T, ByRef arg8 As T, ByRef arg9 As T, ByRef arg10 As T) As T
972         arg1 = source
973         arg2 = source
974         arg3 = source
975         arg4 = source
976         arg5 = source
977         arg6 = source
978         arg7 = source
979         arg8 = source
980         arg9 = source
981         arg10 = source
982         Return source
983     End Function
984     ''' <summary>
985     ''' Copy the source value directly to the target variable and then return the source value.
986     ''' </summary>
987     ''' <typeparam name="T"></typeparam>
988     ''' <param name="source"></param>
989     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T, ByRef arg7 As T, ByRef arg8 As T, ByRef arg9 As T, ByRef arg10 As T, ByRef arg11 As T) As T
990         arg1 = source
991         arg2 = source
992         arg3 = source
993         arg4 = source
994         arg5 = source
995         arg6 = source
996         arg7 = source
997         arg8 = source
998         arg9 = source
999         arg10 = source
1000         arg11 = source
1001         Return source
1002     End Function
1003     ''' <summary>
1004     ''' Copy the source value directly to the target variable and then return the source value.
1005     ''' </summary>
1006     ''' <typeparam name="T"></typeparam>
1007     ''' <param name="source"></param>
1008     <Extension> Public Function ShadowCopy(Of T)(source As T, ByRef arg1 As T, ByRef arg2 As T, ByRef arg3 As T, ByRef arg4 As T, ByRef arg5 As T, ByRef arg6 As T, ByRef arg7 As T, ByRef arg8 As T, ByRef arg9 As T, ByRef arg10 As T, ByRef arg11 As T, ByRef arg12 As T) As T
1009         arg1 = source
1010         arg2 = source
1011         arg3 = source
1012         arg4 = source
1013         arg5 = source
1014         arg6 = source
1015         arg7 = source
1016         arg8 = source
1017         arg9 = source
1018         arg10 = source
1019         arg11 = source
1020         arg12 = source
1021         Return source
1022     End Function
1023 #End Region
1024
1025 #If NET_40 = 0 Then
1026
1027     ''' <summary>
1028     ''' Modify target object property value using a <paramref name="valueModifier">specific value provider</paramref> and then return original instance object.
1029     ''' (修改目标对象的属性之后返回目标对象)
1030     ''' </summary>
1031     ''' <typeparam name="T"></typeparam>
1032     ''' <param name="obj"></param>
1033     ''' <returns></returns>
1034     ''' <remarks></remarks>
1035     <Extension> Public Function ModifyValue(Of T As Class)([property] As PropertyInfo, obj As T, valueModifier As Func(Of ObjectObject)) As T
1036         Dim Value As Object = [property].GetValue(obj)
1037         Value = valueModifier(Value)
1038         Call [property].SetValue(obj, Value)
1039
1040         Return obj
1041     End Function
1042 #End If
1043
1044 #If FRAMEWORD_CORE Then
1045     ''' <summary>
1046     ''' Insert data or update the exists data in the dictionary, if the target object with <see cref="INamedValue.Key"/> 
1047     ''' is not exists in the dictionary, then will be insert, else the old value will be replaced with the parameter 
1048     ''' value <paramref name="item"/>.
1049     ''' (向字典对象之中更新或者插入新的数据,假若目标字典对象之中已经存在了一个数据的话,则会将原有的数据覆盖,并返回原来的数据)
1050     ''' </summary>
1051     ''' <typeparam name="T"></typeparam>
1052     ''' <param name="dict"></param>
1053     ''' <param name="item"></param>
1054     ''' <returns></returns>
1055     ''' <remarks></remarks>
1056     <Extension> Public Function InsertOrUpdate(Of T As INamedValue)(ByRef dict As Dictionary(Of String, T), item As T) As T
1057         Dim pre As T
1058
1059         If dict.ContainsKey(item.Key) Then
1060             pre = dict(item.Key)
1061
1062             Call dict.Remove(item.Key)
1063             Call $"data was updated: {Scripting.ToString(pre)} -> {item.Key}".__DEBUG_ECHO
1064         Else
1065             pre = item
1066         End If
1067
1068         Call dict.Add(item.Key, item)
1069
1070         Return pre
1071     End Function
1072
1073     ''' <summary>
1074     ''' Remove target object from dictionary.
1075     ''' </summary>
1076     ''' <typeparam name="T"></typeparam>
1077     ''' <param name="dict"></param>
1078     ''' <param name="item"></param>
1079     ''' <returns></returns>
1080     <Extension> Public Function Remove(Of T As INamedValue)(ByRef dict As Dictionary(Of String, T), item As T) As T
1081         Call dict.Remove(item.Key)
1082         Return item
1083     End Function
1084
1085     <Extension> Public Function AddRange(Of T As INamedValue)(ByRef dict As Dictionary(Of String, T), data As IEnumerable(Of T)) As Dictionary(Of String, T)
1086         For Each x As T In data
1087             Call InsertOrUpdate(dict, x)
1088         Next
1089
1090         Return dict
1091     End Function
1092 #End If
1093
1094     ''' <summary>
1095     ''' The <see cref="StringBuilder"/> object its content is nothing?
1096     ''' </summary>
1097     ''' <param name="sBuilder"></param>
1098     ''' <returns></returns>
1099     <MethodImpl(MethodImplOptions.AggressiveInlining)>
1100     <Extension> Public Function IsNullOrEmpty(sBuilder As StringBuilder) As Boolean
1101         Return sBuilder Is Nothing OrElse sBuilder.Length = 0
1102     End Function
1103
1104     ''' <summary>
1105     ''' Merge the target array collection into one collection.(将目标数组的集合合并为一个数组)
1106     ''' </summary>
1107     ''' <typeparam name="T"></typeparam>
1108     ''' <param name="source"></param>
1109     ''' <returns></returns>
1110     ''' <remarks></remarks>
1111     <MethodImpl(MethodImplOptions.AggressiveInlining)>
1112     <Extension> Public Function ToVector(Of T)(source As IEnumerable(Of IEnumerable(Of T))) As T()
1113         Return Unlist(source).ToArray
1114     End Function
1115
1116     ''' <summary>
1117     ''' Empty list will be skip and ignored.
1118     ''' (这是一个安全的方法,空集合会被自动跳过,并且这个函数总是返回一个集合不会返回空值)
1119     ''' </summary>
1120     ''' <typeparam name="T"></typeparam>
1121     ''' <param name="source"></param>
1122     ''' <returns></returns>
1123     <Extension> Public Function Unlist(Of T)(source As IEnumerable(Of IEnumerable(Of T))) As List(Of T)
1124         Dim list As New List(Of T)
1125
1126         For Each line As IEnumerable(Of T) In source
1127             If Not line Is Nothing Then
1128                 Call list.AddRange(collection:=line)
1129             End If
1130         Next
1131
1132         Return list
1133     End Function
1134
1135     ''' <summary>
1136     ''' Merge the target array collection into one collection.
1137     ''' (将目标数组的集合合并为一个数组,这个方法是提供给超大的集合的,即元素的数目非常的多的,即超过了<see cref="Integer"></see>的上限值)
1138     ''' </summary>
1139     ''' <typeparam name="T"></typeparam>
1140     ''' <param name="source"></param>
1141     ''' <returns></returns>
1142     ''' <remarks></remarks>
1143     <Extension> Public Function MatrixToUltraLargeVector(Of T)(source As IEnumerable(Of T())) As LinkedList(Of T)
1144         Dim lnkList As LinkedList(Of T) = New LinkedList(Of T)
1145
1146         For Each Line As T() In source
1147             For Each item As T In Line
1148                 Call lnkList.AddLast(item)
1149             Next
1150         Next
1151
1152         Return lnkList
1153     End Function
1154
1155     ''' <summary>
1156     ''' Add a linked list of a collection of specific type of data.
1157     ''' </summary>
1158     ''' <typeparam name="T"></typeparam>
1159     ''' <param name="list"></param>
1160     ''' <param name="data"></param>
1161     ''' <returns></returns>
1162     <Extension> Public Function AddRange(Of T)(list As LinkedList(Of T), data As IEnumerable(Of T)) As LinkedList(Of T)
1163         For Each item As T In data
1164             Call list.AddLast(item)
1165         Next
1166
1167         Return list
1168     End Function
1169
1170     ''' <summary>
1171     ''' 矩阵转置: 将矩阵之中的元素进行行列位置的互换
1172     ''' </summary>
1173     ''' <typeparam name="T">矩阵之中的元素类型</typeparam>
1174     ''' <param name="MAT">为了方便理解和使用,矩阵使用数组的数组来表示的</param>
1175     ''' <returns></returns>
1176     ''' <remarks></remarks>
1177     <Extension> Public Function MatrixTranspose(Of T)(MAT As IEnumerable(Of T())) As T()()
1178         Dim LQuery As T()() = (From i As Integer
1179                                In MAT.First.Sequence
1180                                Select (From Line As T() In MAT Select Line(i)).ToArray).ToArray
1181         Return LQuery
1182     End Function
1183
1184     ''' <summary>
1185     ''' 将矩阵之中的元素进行行列位置的互换,请注意,假若长度不一致的话,会按照最短的元素来转置,故而使用本函数可能会造成一些信息的丢失
1186     ''' </summary>
1187     ''' <typeparam name="T"></typeparam>
1188     ''' <param name="MAT"></param>
1189     ''' <returns></returns>
1190     ''' <remarks></remarks>
1191     <Extension> Public Function MatrixTransposeIgnoredDimensionAgreement(Of T)(MAT As IEnumerable(Of T())) As T()()
1192         Dim LQuery = (From i As Integer
1193                       In (From n As T()
1194                           In MAT
1195                           Select n.Length
1196                           Order By Length Ascending).First.Sequence
1197                       Select (From Line In MAT Select Line(i)).ToArray).ToArray
1198         Return LQuery
1199     End Function
1200
1201     ''' <summary>
1202     ''' 
1203     ''' </summary>
1204     ''' <param name="DIR">The source directory.</param>
1205     ''' <param name="moveTo"></param>
1206     ''' <param name="Split"></param>
1207     ''' <returns></returns>
1208 #If FRAMEWORD_CORE Then
1209     <ExportAPI("Mv.Split")>
1210     Public Function SplitMV(DIR As String, <Parameter("DIR.MoveTo")> moveTo As String, Split As IntegerAs Integer
1211 #Else
1212     Public Function SplitMV(dir As String, moveto As String, split As IntegerAs Integer
1213 #End If
1214         Dim Files As String() = FileIO.FileSystem.GetFiles(DIR, FileIO.SearchOption.SearchTopLevelOnly).ToArray
1215         Dim n As Integer
1216         Dim m As Integer = 1
1217
1218         For i As Integer = 0 To Files.Length - 1
1219             If n < Split Then
1220                 Call FileIO.FileSystem.MoveFile(Files(i), String.Format("{0}_{1}/{2}", moveTo, m, FileIO.FileSystem.GetFileInfo(Files(i)).Name))
1221                 n += 1
1222             Else
1223                 n = 0
1224                 m += 1
1225             End If
1226         Next
1227
1228         Return 0
1229     End Function
1230
1231 #If FRAMEWORD_CORE Then
1232     ''' <summary>
1233     ''' The target parameter <paramref name="n"/> value is NaN or not a real number or not?
1234     ''' (判断目标实数是否为一个无穷数或者非计算的数字,产生的原因主要来自于除0运算结果或者达到了
1235     ''' <see cref="Double"></see>的上限或者下限)
1236     ''' </summary>
1237     ''' <param name="n"></param>
1238     ''' <returns></returns>
1239     ''' <remarks></remarks>
1240     <ExportAPI("Double.Is.NA",
1241                Info:="Is this double type of the number is an NA type infinity number. this is major comes from the devided by ZERO.")>
1242     <MethodImpl(MethodImplOptions.AggressiveInlining)>
1243     <Extension> Public Function IsNaNImaginary(n As DoubleAs Boolean
1244 #Else
1245     <Extension> Public Function Is_NA_UHandle(n As DoubleAs Boolean
1246 #End If
1247         Return Double.IsNaN(n) OrElse
1248             Double.IsInfinity(n) OrElse
1249             Double.IsNegativeInfinity(n) OrElse
1250             Double.IsPositiveInfinity(n)
1251     End Function
1252
1253     <MethodImpl(MethodImplOptions.AggressiveInlining)>
1254     <Extension> Public Function IsNaNImaginary(n As SingleAs Boolean
1255         Return Single.IsNaN(n) OrElse
1256             Single.IsInfinity(n) OrElse
1257             Single.IsNegativeInfinity(n) OrElse
1258             Single.IsPositiveInfinity(n)
1259     End Function
1260 #If FRAMEWORD_CORE Then
1261
1262     ''' <summary>
1263     ''' Fuzzy match two string, this is useful for the text query or searching.
1264     ''' (请注意,这个函数是不会自动转换大小写的,如果是需要字符大小写不敏感,
1265     ''' 请先将query以及subject都转换为小写)
1266     ''' </summary>
1267     ''' <param name="query"></param>
1268     ''' <param name="Subject"></param>
1269     ''' <returns></returns>
1270     ''' <remarks></remarks>
1271     <ExportAPI("FuzzyMatch",
1272                Info:="Fuzzy match two string, this is useful for the text query or searching.")>
1273     <Extension> Public Function FuzzyMatching(query$, subject$, Optional tokenbased As Boolean = TrueOptional cutoff# = 0.8) As Boolean
1274         If tokenbased Then
1275             Dim similarity# = Evaluate(query, subject,,, )
1276             Return similarity >= cutoff
1277         Else
1278             Dim dist = LevenshteinDistance.ComputeDistance(query, subject)
1279             If dist Is Nothing Then
1280                 Return False
1281             Else
1282                 Return dist.MatchSimilarity >= cutoff
1283             End If
1284         End If
1285     End Function
1286 #End If
1287
1288     ''' <summary>
1289     ''' 这个是一个安全的方法,假若下标越界或者目标数据源为空的话,则会返回空值
1290     ''' </summary>
1291     ''' <typeparam name="T"></typeparam>
1292     ''' <param name="source"></param>
1293     ''' <param name="index"></param>
1294     ''' <returns></returns>
1295 #If FRAMEWORD_CORE Then
1296     <ExportAPI("Get.Item")>
1297     <Extension> Public Function GetItem(Of T)(source As IEnumerable(Of T), index As IntegerAs T
1298 #Else
1299     <Extension> Public Function GetItem(Of T)(source As IEnumerable(Of T), index As IntegerAs T
1300 #End If
1301         If source Is Nothing Then
1302             Return Nothing
1303         Else
1304             Return source.ElementAtOrDefault(index)
1305         End If
1306     End Function
1307
1308     ''' <summary>
1309     ''' 求取该数据集的标准差
1310     ''' </summary>
1311     ''' <param name="data"></param>
1312     ''' <returns></returns>
1313     ''' <remarks></remarks>
1314     '''
1315     <ExportAPI("StdError")>
1316     <Extension> Public Function StdError(data As IEnumerable(Of Double)) As Double
1317         Dim Average As Double = data.Average
1318         Dim Sum = (From n As Double In data Select (n - Average) ^ 2).Sum
1319         Sum /= data.Count
1320         Return Global.System.Math.Sqrt(Sum)
1321     End Function
1322
1323     ''' <summary>
1324     ''' The first element in a collection.
1325     ''' </summary>
1326     Public Const Scan0 As Integer = 0
1327
1328     ''' <summary>
1329     ''' 函数只返回有重复的数据
1330     ''' </summary>
1331     ''' <typeparam name="T"></typeparam>
1332     ''' <typeparam name="TTag"></typeparam>
1333     ''' <param name="source"></param>
1334     ''' <param name="getKey"></param>
1335     ''' <returns></returns>
1336     <Extension> Public Function CheckDuplicated(Of T, TTag)(source As IEnumerable(Of T),
1337                                                             getKey As Func(Of T, TTag)) _
1338                                                                    As GroupResult(Of T, TTag)()
1339         Dim Groups = From x As T
1340                      In source
1341                      Select x
1342                      Group x By tag = getKey(x) Into Group '
1343         Dim duplicates As GroupResult(Of T, TTag)() =
1344             LinqAPI.Exec(Of GroupResult(Of T, TTag)) <=
1345  _
1346                 From g
1347                 In Groups.AsParallel
1348                 Where g.Group.Count > 1
1349                 Select New GroupResult(Of T, TTag) With {
1350                     .Tag = g.tag,
1351                     .Group = g.Group.ToArray
1352                 }
1353
1354         Return duplicates
1355     End Function
1356
1357     ''' <summary>
1358     ''' 移除重复的对象,这个函数是根据对象所生成的标签来完成的
1359     ''' </summary>
1360     ''' <typeparam name="T"></typeparam>
1361     ''' <typeparam name="Tag"></typeparam>
1362     ''' <param name="source"></param>
1363     ''' <param name="getKey">得到对象的标签</param>
1364     ''' <returns></returns>
1365     <Extension> Public Function RemoveDuplicates(Of T, Tag)(source As IEnumerable(Of T), getKey As Func(Of T, Tag)) As T()
1366         Dim Groups = From obj As T
1367                      In source
1368                      Select obj
1369                      Group obj By objTag = getKey(obj) Into Group '
1370         Dim LQuery = (From obj In Groups Select obj.Group.First).ToArray
1371         Return LQuery
1372     End Function
1373
1374 #If FRAMEWORD_CORE Then
1375
1376     ''' <summary>
1377     ''' Remove all of the null object in the target object collection.
1378     ''' (这个是一个安全的方法,假若目标集合是空值,则函数会返回一个空的集合)
1379     ''' </summary>
1380     ''' <typeparam name="T"></typeparam>
1381     ''' <param name="source"></param>
1382     ''' <returns></returns>
1383     ''' <remarks></remarks>
1384     '''
1385     <ExportAPI("NullValue.Trim"Info:="Remove all of the null object in the target object collection")>
1386     <Extension> Public Function TrimNull(Of T As Class)(source As IEnumerable(Of T)) As T()
1387 #Else
1388     ''' <summary>
1389     ''' Remove all of the null object in the target object collection
1390     ''' </summary>
1391     ''' <typeparam name="T"></typeparam>
1392     ''' <param name="Collection"></param>
1393     ''' <returns></returns>
1394     ''' <remarks></remarks>
1395     <Extension> Public Function TrimNull(Of T As Class)(source As IEnumerable(Of T)) As T()
1396 #End If
1397         If source Is Nothing Then
1398             Return New T() {}
1399         Else
1400             Return (From x In source Where Not x Is Nothing Select x).ToArray
1401         End If
1402     End Function
1403
1404     ''' <summary>
1405     ''' Remove all of the null object in the target object collection
1406     ''' </summary>
1407     ''' <param name="source"></param>
1408     ''' <returns></returns>
1409     ''' <remarks></remarks>
1410     <Extension> Public Function TrimNull(source As IEnumerable(Of String)) As String()
1411         If source Is Nothing Then
1412             Return New String() {}
1413         Else
1414             Return (From x In source Where Not x.StringEmpty Select x).ToArray
1415         End If
1416     End Function
1417
1418     ''' <summary>
1419     ''' Return a collection with randomize element position in <paramref name="source">the original collection</paramref>.
1420     ''' (从原有序序列中获取一个随机元素的序列)
1421     ''' </summary>
1422     ''' <typeparam name="T"></typeparam>
1423     ''' <param name="source"></param>
1424     ''' <returns></returns>
1425     ''' <remarks></remarks>
1426     '''
1427     <ExportAPI("Shuffles")>
1428     <Extension> Public Function Shuffles(Of T)(source As IEnumerable(Of T)) As T()
1429         Dim tmp As New List(Of T)(source)
1430         Dim buf As T() = New T(tmp.Count - 1) {}
1431         Dim rand As New Random(Seed:=Math.Seed)
1432         Dim l As Integer = tmp.Count - 1
1433
1434         For i As Integer = 0 To buf.Length - 1
1435             Dim index As Integer = rand.Next(minValue:=0, maxValue:=l)
1436             buf(i) = tmp(index)
1437             Call tmp.RemoveAt(index)
1438             l -= 1
1439         Next
1440
1441         Return buf
1442     End Function
1443
1444     ''' <summary>
1445     ''' 返回n长度的序列数值,这些序列数值是打乱顺序的,但是升序排序之后会得到1:n的序列
1446     ''' 请注意,这个序列并不是随机数,而是将n长度的序列之中的元素打乱顺序的结果
1447     ''' </summary>
1448     ''' <param name="n"></param>
1449     ''' <returns></returns>
1450     <ExportAPI("Sequence.Random")>
1451     <Extension> Public Function SeqRandom(n As IntegerAs Integer()
1452         Dim source As Integer() = n.Sequence.ToArray
1453         Dim Random As Integer() = source.Shuffles
1454         Return Random
1455     End Function
1456
1457     ''' <summary>
1458     ''' 随机的在目标集合中选取指定数目的子集合
1459     ''' </summary>
1460     ''' <typeparam name="T"></typeparam>
1461     ''' <param name="source"></param>
1462     ''' <param name="counts">当目标数目大于或者等于目标集合的数目的时候,则返回目标集合</param>
1463     ''' <returns></returns>
1464     ''' <remarks></remarks>
1465     <Extension> Public Function TakeRandomly(Of T)(source As IEnumerable(Of T), counts%) As T()
1466         Dim array As T() = source.ToArray
1467
1468         If counts >= array.Length Then
1469             Return source
1470         Else
1471             Dim out As T() = New T(counts - 1) {}
1472             Dim input As New List(Of T)(array)
1473             Dim random As New Random
1474
1475             For i As Integer = 0 To counts - 1
1476                 Dim ind As Integer = random.Next(input.Count)
1477                 out(i) = input(ind)
1478                 Call input.RemoveAt(ind)
1479             Next
1480
1481             Return out
1482         End If
1483     End Function
1484
1485     ''' <summary>
1486     ''' Convert target object type collection into a string array using the Object.ToString() interface function.
1487     ''' </summary>
1488     ''' <typeparam name="T"></typeparam>
1489     ''' <param name="source"></param>
1490     ''' <returns></returns>
1491     ''' <remarks></remarks>
1492     <Extension> Public Function ToStringArray(Of T)(source As IEnumerable(Of T)) As String()
1493         If source Is Nothing Then
1494             Return {}
1495         End If
1496
1497         Dim LQuery$() = LinqAPI.Exec(Of String) _
1498  _
1499             () <= From item As T
1500                   In source
1501                   Let strItem As String = item?.ToString
1502                   Select strItem
1503
1504         Return LQuery
1505     End Function
1506
1507     <Extension> Public Sub Swap(Of T)(ByRef array As T(), a%, b%)
1508         Dim tmp As T = array(a)
1509         array(a) = array(b)
1510         array(b) = tmp
1511     End Sub
1512
1513     ''' <summary>
1514     ''' Swap the value in the two variables.
1515     ''' </summary>
1516     ''' <typeparam name="T"></typeparam>
1517     ''' <param name="obj1"></param>
1518     ''' <param name="obj2"></param>
1519     ''' <remarks></remarks>
1520     <Extension> Public Sub SwapWith(Of T)(ByRef obj1 As T, ByRef obj2 As T)
1521         Dim objTemp As T = obj1
1522         obj1 = obj2
1523         obj2 = objTemp
1524     End Sub
1525
1526     ''' <summary>
1527     ''' Swap the two item position in the target <paramref name="list">list</paramref>.
1528     ''' </summary>
1529     ''' <typeparam name="T"></typeparam>
1530     ''' <param name="list"></param>
1531     ''' <param name="obj_1"></param>
1532     ''' <param name="obj_2"></param>
1533     <Extension> Public Sub SwapItem(Of T)(ByRef list As List(Of T), obj_1 As T, obj_2 As T)
1534         Dim idx_1 As Integer = list.IndexOf(obj_1)
1535         Dim idx_2 As Integer = list.IndexOf(obj_2)
1536
1537         If idx_1 = -1 OrElse idx_2 = -1 Then
1538             Return
1539         End If
1540
1541         Call list.RemoveAt(idx_1)
1542         Call list.Insert(idx_1, obj_2)
1543         Call list.RemoveAt(idx_2)
1544         Call list.Insert(idx_2, obj_2)
1545     End Sub
1546
1547 #If FRAMEWORD_CORE Then
1548     ''' <summary>
1549     ''' Add array location index value for the <see cref="IAddressOf"/> elements in the sequence.
1550     ''' (为列表中的对象添加对象句柄值)
1551     ''' </summary>
1552     ''' <param name="source"></param>
1553     ''' <remarks></remarks>
1554     <Extension> Public Function WriteAddress(Of T As IAddressOf)(ByRef source As IEnumerable(Of T), Optional offset As Integer = 0) As T()
1555         Dim list As New List(Of T)
1556         Dim i As Integer = offset
1557
1558         For Each x As T In source
1559             Call x.Assign(address:=i)
1560
1561             i += 1
1562             list += x
1563         Next
1564
1565         Return list
1566     End Function
1567 #End If
1568
1569 #If FRAMEWORD_CORE Then
1570     ''' <summary>
1571     ''' Gets the subscript index of a generic collection.(获取某一个集合的下标的集合)
1572     ''' </summary>
1573     ''' <typeparam name="T">集合中的元素为任意类型的</typeparam>
1574     ''' <param name="source">目标集合对象</param>
1575     ''' <returns>A integer array of subscript index of the target generic collection.</returns>
1576     ''' <remarks></remarks>
1577     '''
1578     <ExportAPI("Sequence.Index"Info:="Gets the subscript index of a generic collection.")>
1579     <Extension> Public Iterator Function Sequence(Of T)(
1580                                         <Parameter("source""")> source As IEnumerable(Of T),
1581                                         <Parameter("index.OffSet""")> Optional offSet% = 0) _
1582                                      As <FunctionReturns("A integer array of subscript index of the target generic collection.")> IEnumerable(Of Integer)
1583 #Else
1584     ''' <summary>
1585     ''' 获取某一个集合的下标的集合
1586     ''' </summary>
1587     ''' <typeparam name="T">集合中的元素为任意类型的</typeparam>
1588     ''' <param name="Collection">目标集合对象</param>
1589     ''' <returns></returns>
1590     ''' <remarks></remarks>
1591     '''
1592     <Extension> Public Iterator Function Sequence(Of T)(source As IEnumerable(Of T), Optional offset As Integer = 0) As IEnumerable(Of Integer)
1593 #End If
1594         If source Is Nothing Then
1595             Return
1596         Else
1597             Dim i As Integer = offSet
1598
1599             For Each x As T In source
1600                 Yield i
1601                 i += 1
1602             Next
1603         End If
1604     End Function
1605
1606     <Extension> Public Iterator Function LongSeq(Of T)(source As IEnumerable(Of T), Optional offset% = 0) As IEnumerable(Of Long)
1607         If source Is Nothing Then
1608             Return
1609         Else
1610             Dim i As Long = offset
1611
1612             For Each x As T In source
1613                 Yield i
1614                 i += 1
1615             Next
1616         End If
1617     End Function
1618
1619     <Extension> Public Function LongSeq(n&) As Long()
1620         Dim array&() = New Long(n - 1) {}
1621         For i As Long = 0 To array.Length - 1
1622             array(i) = i
1623         Next
1624         Return array
1625     End Function
1626
1627     <Extension> Public Function Takes(Of T)(source As T(), count As IntegerAs T()
1628         Dim bufs As T() = New T(count - 1) {}
1629         Call Array.ConstrainedCopy(source, Scan0, bufs, Scan0, count)
1630         Return bufs
1631     End Function
1632
1633     ''' <summary>
1634     ''' 将目标键值对对象的集合转换为一个字典对象
1635     ''' </summary>
1636     ''' <typeparam name="TKey"></typeparam>
1637     ''' <typeparam name="TValue"></typeparam>
1638     ''' <param name="source"></param>
1639     ''' <param name="remoteDuplicates">当这个参数为False的时候,出现重复的键名会抛出错误,当为True的时候,有重复的键名存在的话,可能会丢失一部分的数据</param>
1640     ''' <returns></returns>
1641     ''' <remarks></remarks>
1642     <Extension> Public Function ToDictionary(Of TKey, TValue)(
1643                                 source As IEnumerable(Of KeyValuePair(Of TKey, TValue)),
1644                        Optional remoteDuplicates As Boolean = FalseAs Dictionary(Of TKey, TValue)
1645
1646         If remoteDuplicates Then
1647             Dim table As New Dictionary(Of TKey, TValue)
1648
1649             For Each x In source
1650                 If table.ContainsKey(x.Key) Then
1651                     Call $"[Duplicated] {x.Key.ToString}".PrintException
1652                 Else
1653                     Call table.Add(x.Key, x.Value)
1654                 End If
1655             Next
1656
1657             Return table
1658         Else
1659             Dim dictionary As Dictionary(Of TKey, TValue) =
1660                 source.ToDictionary(Function(x) x.Key,
1661                                     Function(x) x.Value)
1662             Return dictionary
1663         End If
1664     End Function
1665
1666     ' 2018-6-11
1667     '
1668     ' 因为迭代器在访问linq序列的时候,对于非空序列,下面的IsNullOrEmpty函数总是会产生一次迭代
1669     ' 这个迭代可能会导致元素丢失的bug产生
1670     ' 所以在这里将这个linq函数注释掉
1671     ' 以后只需要判断迭代器是否是空值即可
1672
1673     '''' <summary>
1674     '''' This object collection is a null object or contains zero count items.
1675     '''' </summary>
1676     '''' <typeparam name="T"></typeparam>
1677     '''' <param name="source"></param>
1678     '''' <returns></returns>
1679     '''' <remarks></remarks>
1680     '<Extension> Public Function IsNullOrEmpty(Of T)(source As IEnumerable(Of T)) As Boolean
1681     '    If source Is Nothing Then
1682     '        Return True
1683     '    End If
1684
1685     '    Dim i% = -1
1686
1687     '    Using [try] = source.GetEnumerator
1688     '        Do While [try].MoveNext
1689
1690     '            ' debug view
1691     '            Dim null = [try].Current
1692
1693     '            ' 假若是存在元素的,则i的值会为零
1694     '            ' Some type of linq sequence not support this method.
1695     '            ' [try].Reset()
1696     '            i += 1
1697
1698     '            ' If is not empty, then this For loop will be used.
1699     '            Return False
1700     '        Loop
1701     '    End Using
1702
1703     '    ' 由于没有元素,所以For循环没有进行,i变量的值没有发生变化
1704     '    ' 使用count拓展进行判断或导致Linq被执行两次,现在使用FirstOrDefault来判断,
1705     '    ' 主需要查看第一个元素而不是便利整个Linq查询枚举, 从而提高了效率
1706     '    ' Due to the reason of source is empty, no elements, 
1707     '    ' so that i value Is Not changed as the For loop 
1708     '    ' didn 't used.
1709     '    Return i = -1
1710     'End Function
1711
1712     ''' <summary>
1713     ''' 字典之中是否是没有任何数据的?
1714     ''' </summary>
1715     ''' <typeparam name="TKey"></typeparam>
1716     ''' <typeparam name="TValue"></typeparam>
1717     ''' <param name="dict"></param>
1718     ''' <returns></returns>
1719     <Extension> Public Function IsNullOrEmpty(Of TKey, TValue)(dict As IDictionary(Of TKey, TValue)) As Boolean
1720         If dict Is Nothing Then
1721             Return True
1722         End If
1723         Return dict.Count = 0
1724     End Function
1725
1726     <Extension>
1727     Public Function IsNullOrEmpty(Of T As INamedValue)(table As Dictionary(Of T)) As Boolean
1728         If table Is Nothing Then
1729             Return True
1730         Else
1731             Return table.Count = 0
1732         End If
1733     End Function
1734
1735     ''' <summary>
1736     ''' 字典之中是否是没有任何数据的?
1737     ''' </summary>
1738     ''' <typeparam name="TKey"></typeparam>
1739     ''' <typeparam name="TValue"></typeparam>
1740     ''' <param name="dict"></param>
1741     ''' <returns></returns>
1742     <Extension> Public Function IsNullOrEmpty(Of TKey, TValue)(dict As IReadOnlyDictionary(Of TKey, TValue)) As Boolean
1743         If dict Is Nothing Then
1744             Return True
1745         End If
1746         Return dict.Count = 0
1747     End Function
1748
1749     <Extension> Public Function IsNullOrEmpty(Of TKey, TValue)(dict As ReadOnlyDictionary(Of TKey, TValue)) As Boolean
1750         If dict Is Nothing Then
1751             Return True
1752         End If
1753         Return dict.Count = 0
1754     End Function
1755
1756     ''' <summary>
1757     ''' 字典之中是否是没有任何数据的?
1758     ''' </summary>
1759     ''' <typeparam name="TKey"></typeparam>
1760     ''' <typeparam name="TValue"></typeparam>
1761     ''' <param name="dict"></param>
1762     ''' <returns></returns>
1763     <Extension> Public Function IsNullOrEmpty(Of TKey, TValue)(dict As Dictionary(Of TKey, TValue)) As Boolean
1764         If dict Is Nothing Then
1765             Return True
1766         End If
1767         Return dict.Count = 0
1768     End Function
1769
1770     ''' <summary>
1771     ''' 这个队列之中是否是没有任何数据的?
1772     ''' </summary>
1773     ''' <typeparam name="T"></typeparam>
1774     ''' <param name="queue"></param>
1775     ''' <returns></returns>
1776     <Extension> Public Function IsNullOrEmpty(Of T)(queue As Queue(Of T)) As Boolean
1777         If queue Is Nothing Then
1778             Return True
1779         End If
1780         Return queue.Count = 0
1781     End Function
1782
1783     <Extension>
1784     Public Function IsNullorEmpty(Of T)(vector As Vector(Of T)) As Boolean
1785         If vector Is Nothing Then
1786             Return True
1787         End If
1788         Return vector.Length = 0
1789     End Function
1790
1791     <Extension>
1792     Public Function IsNullOrEmpty(args As ArgumentCollection) As Boolean
1793         If args Is Nothing Then
1794             Return True
1795         End If
1796         Return args.Count = 0
1797     End Function
1798
1799     ''' <summary>
1800     ''' 这个动态列表之中是否是没有任何数据的?
1801     ''' </summary>
1802     ''' <typeparam name="T"></typeparam>
1803     ''' <param name="list"></param>
1804     ''' <returns></returns>
1805     <Extension> Public Function IsNullOrEmpty(Of T)(list As ICollection(Of T)) As Boolean
1806         If list Is Nothing Then
1807             Return True
1808         End If
1809         Return list.Count = 0
1810     End Function
1811
1812     <Extension> Public Function IsNullOrEmpty(Of T)(list As IList(Of T)) As Boolean
1813         If list Is Nothing Then
1814             Return True
1815         End If
1816         Return list.Count = 0
1817     End Function
1818
1819     <Extension> Public Function IsNullOrEmpty(Of T)(list As System.Collections.Generic.List(Of T)) As Boolean
1820         If list Is Nothing Then
1821             Return True
1822         End If
1823         Return list.Count = 0
1824     End Function
1825
1826     <Extension>
1827     Public Function IsNullOrEmpty(Of T)(collection As IReadOnlyCollection(Of T)) As Boolean
1828         If collection Is Nothing Then
1829             Return True
1830         Else
1831             Return collection.Count = 0
1832         End If
1833     End Function
1834
1835     <Extension>
1836     Public Function IsNullOrEmpty(Of T)(collection As ReadOnlyCollection(Of T)) As Boolean
1837         If collection Is Nothing Then
1838             Return True
1839         Else
1840             Return collection.Count = 0
1841         End If
1842     End Function
1843
1844     ''' <summary>
1845     ''' This object array is a null object or contains zero count items.(判断某一个对象数组是否为空)
1846     ''' </summary>
1847     ''' <typeparam name="T"></typeparam>
1848     ''' <returns></returns>
1849     ''' <remarks></remarks>
1850     <Extension> Public Function IsNullOrEmpty(Of T)(array As T()) As Boolean
1851         Return array Is Nothing OrElse array.Length = 0
1852     End Function
1853
1854     ''' <summary>
1855     ''' 0 for null object
1856     ''' </summary>
1857     ''' <typeparam name="T"></typeparam>
1858     ''' <param name="array"></param>
1859     ''' <returns></returns>
1860     <Extension> Public Function GetLength(Of T)(array As T()) As Integer
1861         If array Is Nothing Then
1862             Return 0
1863         Else
1864             Return array.Length
1865         End If
1866     End Function
1867
1868     <Extension> Public Function GetLength(Of T)(collect As IEnumerable(Of T)) As Integer
1869         If collect Is Nothing Then
1870             Return 0
1871         Else
1872             Return collect.Count
1873         End If
1874     End Function
1875
1876 #If FRAMEWORD_CORE Then
1877
1878     ''' <summary>
1879     ''' 执行一个命令行语句,并返回一个IO重定向对象,以获取被执行的目标命令的标准输出
1880     ''' </summary>
1881     ''' <param name="CLI"></param>
1882     ''' <returns></returns>
1883     ''' <remarks></remarks>
1884     '''
1885     <ExportAPI("Shell")>
1886     <Extension> Public Function Shell(CLI As StringAs IIORedirectAbstract
1887         Return CType(CLI, IORedirect)
1888     End Function
1889 #End If
1890
1891     ''' <summary>
1892     ''' 获取一个实数集合中所有元素的积
1893     ''' </summary>
1894     ''' <param name="source"></param>
1895     ''' <returns></returns>
1896     ''' <remarks></remarks>
1897     '''
1898     <ExportAPI("PI")>
1899     <Extension> Public Function π(source As IEnumerable(Of Double)) As Double
1900         If source Is Nothing Then
1901             Return 0
1902         End If
1903
1904         Dim result# = 1
1905         Dim stepInto As Boolean = False
1906
1907         For Each x As Double In source
1908             stepInto = True
1909             result *= x
1910         Next
1911
1912         If Not stepInto Then
1913             Return 0
1914         Else
1915             Return result
1916         End If
1917     End Function
1918
1919 #If FRAMEWORD_CORE Then
1920
1921     ''' <summary>
1922     ''' Fill the newly created image data with the specific color brush
1923     ''' </summary>
1924     ''' <param name="Image"></param>
1925     ''' <param name="FilledColor"></param>
1926     ''' <remarks></remarks>
1927     <Extension> Public Sub FillBlank(ByRef Image As Image, FilledColor As Brush)
1928         If Image Is Nothing Then
1929             Return
1930         End If
1931         Using gr As Graphics = Graphics.FromImage(Image)
1932             Dim R As New Rectangle(New Point, Image.Size)
1933             Call gr.FillRectangle(FilledColor, R)
1934         End Using
1935     End Sub
1936 #End If
1937
1938     ''' <summary>
1939     ''' Nothing
1940     ''' </summary>
1941     Friend Const null = Nothing
1942     Public Const void As Object = Nothing
1943
1944     ''' <summary>
1945     ''' Remove all of the element in the <paramref name="collection"></paramref> from target <paramref name="List">list</paramref>
1946     ''' </summary>
1947     ''' <typeparam name="T"></typeparam>
1948     ''' <param name="List"></param>
1949     ''' <param name="collection"></param>
1950     ''' <remarks></remarks>
1951     <Extension> Public Sub Removes(Of T)(ByRef List As List(Of T), collection As IEnumerable(Of T))
1952         For Each obj In collection
1953             Call List.Remove(obj)
1954         Next
1955     End Sub
1956
1957 #Region "Removes Last Element"
1958
1959     ''' <summary>
1960     ''' Removes the last element in the List object.(这个拓展函数同时兼容.NET框架的list类型以及sciBASIC之中的list类型)
1961     ''' </summary>
1962     ''' <typeparam name="T"></typeparam>
1963     ''' <param name="dotNETlist"></param>
1964     ''' <returns></returns>
1965     <Extension> Public Function RemoveLast(Of T)(ByRef dotNETlist As System.Collections.Generic.List(Of T)) As System.Collections.Generic.List(Of T)
1966         If dotNETlist.IsNullOrEmpty Then
1967             dotNETlist = New List(Of T)
1968
1969             ' 2018-1-25
1970             ' 需要将0和1分开来看,否则会造成最后一个元素永远都移除不了的bug
1971         ElseIf dotNETlist.Count = 1 Then
1972             dotNETlist.Clear()
1973         Else
1974             Dim i As Integer = dotNETlist.Count - 1
1975             Call dotNETlist.RemoveAt(i)
1976         End If
1977
1978         Return dotNETlist
1979     End Function
1980
1981     ''' <summary>
1982     ''' Removes the last element in the List object.
1983     ''' (这个拓展函数同时兼容.NET框架的list类型以及sciBASIC之中的<see cref="List(Of T)"/>类型)
1984     ''' </summary>
1985     ''' <typeparam name="T"></typeparam>
1986     ''' <param name="list"></param>
1987     ''' <returns></returns>
1988     <Extension> Public Function RemoveLast(Of T)(ByRef list As List(Of T)) As List(Of T)
1989         Return DirectCast(RemoveLast(dotNETlist:=list), List(Of T))
1990     End Function
1991
1992 #End Region
1993
1994     <Extension> Public Function RemoveFirst(Of T)(ByRef list As List(Of T)) As List(Of T)
1995         If list.IsNullOrEmpty OrElse list.Count = 1 Then
1996             list = New List(Of T)
1997         Else
1998             Call list.RemoveAt(Scan0)
1999         End If
2000
2001         Return list
2002     End Function
2003 End Module