تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
إضافة طرائق مخصصة لاستعلامات لينك Linq
#1
كاتب الموضوع : samerselo

يمكنك توسيع مجموعة الطرائق التي يمكنك استخدامها مع استعلامات لينك بإضافة وظائف موسعة للواجهة IEnumerable(T) فإضافة إلى العمليات التقليدية مثل الوسطي أو الحد الأقصى يمكننا مثلا إضافة دالة تجميعية لحساب قيمة وحيدة من سلسلة قيم كما يمكنك إنشاء دالة تشكل مرشح مخصص أو لتحويل سلسلة معينة من البيانات إلى سلسلة أخرى فعندما تقوم بتوسيع الواجهة IEnumerable(T) فأنت تضيف دالات مخصصة لأي مجموعة قابلة للتعداد.
فالمثال التالي يرينا كيفية إنشاء طريقة موسعة تدعى Median لحساب وسطي سلسلة أرقام من النوع Double

كود :
Imports System.Runtime.CompilerServices

Module LINQExtension

' Extension method for the IEnumerable(of T) interface.
' The method accepts only values of the Double type.
<Extension()> _
Function Median(ByVal source As IEnumerable(Of Double)) As Double
If source.Count = 0 Then
Throw New InvalidOperationException("Cannot compute median for an empty set.")
End If

Dim sortedSource = From number In source _
Order By number

Dim itemIndex = sortedSource.Count \ 2

If sortedSource.Count Mod 2 = 0 Then
' Even number of items in list.
Return (sortedSource(itemIndex) + sortedSource(itemIndex - 1)) / 2
Else
' Odd number of items in list.
Return sortedSource(itemIndex)
End If
End Function
End Module
حيث يمكنك استدعاء هذه الطريقة الموسعة من أي مجموعة قابلة للتعداد بنفس الطريقة التي تقوم بها باستدعاء الدالات التجميعية ويرينا المثال التالي كيفية استخدام الطريقة السابقة مع مصفوفة double

كود :
Dim numbers1() As Double = {1.9, 2, 8, 4, 5.7, 6, 7.2, 0}
Dim query1 = Aggregate num In numbers1 Into Median()
MsgBox("Double: Median = " & query1)
فالاستعلام السابق يجب أن ينتج القيمة 4.85 بحسب قيم الدخل
كما يمكن أن نضيف وظائف موسعة محملة Overloaded من أجل كل نوع من أنواع البيانات

كود :
' Integer overload
<Extension()> _
Function Median(ByVal source As IEnumerable(Of Integer)) As Double
Return Aggregate num In source Select CDbl(num) Into med = Median()
End Function
ويكون استخدامها مماثلا

كود :
Dim numbers1() As Double = {1.9, 2, 8, 4, 5.7, 6, 7.2, 0}
Dim query1 = Aggregate num In numbers1 Into Median()
MsgBox("Double: Median = " & query1)

Dim numbers2() As Integer = {1, 2, 3, 4, 5}
Dim query2 = Aggregate num In numbers2 Into Median()
MsgBox("Integer: Median = " & query2)
كما يمكننا إضافة طريقة موسعة محملة تقبل أغراضا عامة Generic Objects وهي تأخذ مفوضا Delegate كمحدد وتستخدمه لتحويل سلسة الأغراض من النوع العام للنوع المحدد ويرينا الكود التالي طريقة محملة لـ Median تأخذ Func(T, TResult) كمحدد مفوض وهذا المفوض يأخذ غرض من نوع عام T ويعيد غرض من النوع Double

كود :
' Generic overload.
<Extension()> _
Function Median(Of T)(ByVal source As IEnumerable(Of T), _
ByVal selector As Func(Of T, Double)) As Double
Return Aggregate num In source Select selector(num) Into med = Median()
End Function
حيث يمكنك استخدام الطريقة Median من اجل سلسلة من الأغراض من أي نوع إذا لم يكن للنوع وظيفته المحملة فيجب عليك عندها تمرير محدد مفوض Delegate Parameter كما يمكنك استخدام تعابير لمدا Lambda Expressions لهذا الغرض كما يمكنك في فيجول بايزيك فقط استخدام قسم Aggregate أو Group By بدلا من استدعاء الطريقة حيث يمكنك تمرير أي قيمة أو تعبير ضمن مجال القسم
ويرينا المثال التالي كيفية استدعاء الطريقة Median من أجل integer أو String فمن أجل النصوص يحتسب طول النصوص في المصفوفة حيث نرى كيفية تمرير Func(T, TResult) للطريقة Median من أجل كل حالة

كود :
Dim numbers3() As Integer = {1, 2, 3, 4, 5}

' You can use num as a parameter for the Median method
' so that the compiler will implicitly convert its value to double.
' If there is no implicit conversion, the compiler will
' display an error message.

Dim query3 = Aggregate num In numbers3 Into Median(num)
MsgBox("Integer: Median = " & query3)
Dim numbers4() As String = {"one", "two", "three", "four", "five"}

' With the generic overload, you can also use numeric properties of objects.

Dim query4 = Aggregate str In numbers4 Into Median(str.Length)
MsgBox("String: Median = " & query4)

' This code produces the following output:
' Integer: Median = 3
' String: Median = 4
يمكننا توسيع الواجهة IEnumerbale(T) بطريقة استعلام مخصصة تعيد سلسلة من القيم وفي هذه الحالة يجب علينا إعادة مجموعة من النوع IEnumerable(T) حيث يمكن استخدام طريقة مماثلة لما ذكر من اجل ترشيح أو تحويل بيانات إلى سلسلة من القيم ويرينا المثال التالي كيفية إنشاء طريقة موسعة تدعى AlternateElements تعيد جميع العناصر الأخرى في المجموعة بدءا من العنصر الأول

كود :
' Extension method for the IEnumerable(of T) interface.
' The method returns every other element of a sequence.
<Extension()> _
Function AlternateElements(Of T)(ByVal source As IEnumerable(Of T)) _
As IEnumerable(Of T)
Dim list As New List(Of T)
Dim i = 0
For Each element In source
If (i Mod 2 = 0) Then
list.Add(element)
End If
i = i + 1
Next
Return list
End Function
حيث يمكنك استدعاء هذه الطريقة الموسعة من أجل أي مجموعة قابلة للتعداد تماما كما تفعل عندما تستدعي أي طريقة أخرى من الواجهةIEnumerbale(T) كما نرى في الكود

كود :
Dim strings() As String = {"a", "b", "c", "d", "e"}
Dim query = strings.AlternateElements()
For Each element In query
MsgBox(element)
Next

' This code produces the following output:
' a
' c
' e
}}}
تم الشكر بواسطة:



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم