الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

إضافة طرائق مخصصة لاستعلامات لينك Linq

بدأه محمد سامر أبو سلو في 11 أبريل 2009 · 0 رد · 408 مشاهدة · في Microsoft Visual Basic.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1

يمكنك توسيع مجموعة الطرائق التي يمكنك استخدامها مع استعلامات لينك بإضافة وظائف موسعة للواجهة 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

عن عائشة رضي الله عنها أن النبي صلى الله عليه وسلم قال: إن الله يحب إذا عمل أحدكم عملا أن يتقنه

نعيب زماننا والعيب فينا ... وما لزماننا عيب سوانا

ونهجو ذا الزمان بغير ذنب ... ولو نطق الزمان لنا هجانا

محمد سامر أبو سلو

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…