السلام عليكم ورحمه الله تعالي وبركاته
ارجو يا جماعه من الناس الجامدين في الoop
يعملوا مثال ولو بسيط عن تركيب الclass وكيفيه وضع ال sub
وما هو الفرق بين Public Shared Function وPublic sub
انا مبرمج جديد في الدوت نت وارجو الافاده افادكم الله
السلام عليكم ورحمه الله تعالي وبركاته
ارجو يا جماعه من الناس الجامدين في الoop
يعملوا مثال ولو بسيط عن تركيب الclass وكيفيه وضع ال sub
وما هو الفرق بين Public Shared Function وPublic sub
انا مبرمج جديد في الدوت نت وارجو الافاده افادكم الله
السلام عليكم
حسب خبرتي الضحلة في OOP
أقول أن الـ Class له أكثر من هيئة و أكثر من طريقة بناء
أما الهيئة مثلاً قد يكون الـ Class لا تستطيع إستخدامه مباشرتً ولكن لا بد أن يتم إرثه وهذا يعرف بـ Abstraction Class
بحيث تستخدم الكلمة المحجوزة MustInherit . وقد يكون غير ذلك .
كذلك قد يكون الـ Class له أكثر من بناء Constructions وهذا البناء يعرف في VB.NET بـ Sub New
وقد يكون هذا البناء يحوي ممررات Parameters بهذا الشكل Sub New (param1,param2,…paramN)
بالنسبة للـبناء Sub New له شروط منها
1 – أن يكون Public , وقد يكون Private بشرط ان يكون وحيد Single Constructor
2 – ثانياً أن يكون مختلف من حيث الممررات أو كمية الممررات
مثلاً لا تستطيع أن تبني 2 Constructors فاضيين من حيث الـ parameters ولا متساويين كذلك .
3 – لا تستطيع أن تستخدم أحد الـ Identifiers لأي متغير فيه بإستثناء الـ Dim فقط .
مثلاً هذا غير مقبول فيه Private myVar As Integer
وهذا مقبول Dim myVar As Integer والسبب أن الـ Dim تعني Local Variable .
بينما Private ليست Local ولكنها خاصة بالـ Class التي أُنشِئت فيه .
كذلك يفضل أن يحتوي الـ Class على مايعرف بالهدم Destruction وهو هدم الـ Class عندما يكون إستنزف أو
أكمل مهمته , و إن كان الـ .NET لايملك هدم حقيقي إلا أنه يعول على سلوكين و عنصر
وأما السلوكان فهما السلوك Finalize و السلوك Dispose
والعنصر هو GC وهذا العنصر لهُ بعض السلوكيات منها مثلاً السلوك Collect و السلوك SuppressFinalize
ولكن منادات السلوك Collect من العنصر GC يعتبر فكرة سيئة .
كذلك لابد من الحذر فيما يتعلق بالـ Destruction
مثلاً عند إستدعاء السلوك Dispose يكون قد قضيت على كل عناصر هذا الـ Class
والسبب أن ريثما يستدعى يكون القالب وهو Class في عِداد المفقودين Invalid to Access .
الفوارق بين هذه العناصر والسلوكيات
فمثلاً السلوك Finalize يستخدمة العنصر GC قبل عملية التجميع Collect
كذلك من الخطأ أن يتم إستدعاء أجراء Procedure أو متغير أو غير ذلك في حدث الـ Finalize
والسبب بسيط جداً كون المُستدعى قد يكون هو في حالة تدمير فينشأ عن مناداةِ رسالة خطأ كون العنصر مفقود
أو غير معروف ويستثنى من هذه القاعدة الـ Debug و الكلمة myBase كونها تنادي الـ parent Class
لآن الـ parent Class لم يُدمر و إنما تم تدمير العنصر الحالي Current Object .
أما السلوك Dispose فيستخدم من قبل المبرمج لِتعجيل عملية الهدم وله معايير منها
1 – أولاً هذا السلوك تابع للواجهه IDisposable وهو Interface بمجرد تطبيقة يتم إدراج السلوك
Dispose هذا الطريقة أي طريقة الإدراج التلقائي وجدت في النسخة 2003 فقط .
2 – كأفضلية نستخدم شرط التحقق قبل الهدم لنعرف هل تم هدمه أم لا If Not Disposed
3 - في عملية إنشاء الـ Class يفضل أن يوضع تحت الإختبار Try Catch وفي الـ Finally يتم مناداة الـ Dispose
بشرط أن يكون السلوك Dispose معرف في الـ Class مع تطبيق الـ Interface الخاص بـالسلوك Dispose .
مثلاً myClass.Dispose() .
هذا بشكل مختصر ومعتصر عن سؤالك حول الـ Class
أما بالنسبة لكل من Sub و Function فالفارق الوحيد هو أن الـ function يقوم بإرجاع قيمة بينما الـ Sub لا
حينما تحتاج بعد عملية معينه بإختبار هل تمت أم لا أو إرجاع قيمة ما بعد العملية التي سيقوم بها الإجراء
ففي هذه الحالة الـ function هو الحل مثال ذلك
تريد أن تعرف هل هذا الزبون مسجل في قاعدة البيانات أم لا فتقوم بكتابة النصوص البرمجية التالية
Private Function ComfirmCustomer(ByVal Name As String) As String
Try
Dim NameReturn As Object
Dim cmd As New SqlCommand("sp_ConfirmCustomer", CnnMain)
cmd.Parameters.Add(New SqlParameter("@critera", _
SqlDbType.NVarChar, 50)).Value = Name
cmd.Parameters("@critera").Direction = _
ParameterDirection.InputOutput
cmd.CommandType = CommandType.StoredProcedure
CnnMain.Open()
NameReturn = cmd.ExecuteScalar()
CnnMain.Close()
If NameReturn Is Nothing Then
Return "NoRecord"
Exit Function
Else
Return cmd.Parameters("@critera").Value.ToString
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Functionكما تلاحظ بعد إغلاق القوس الكلمة As String وهذا يعني أن هذا الـ Function سيعود بقيمة نصية String
اي في هذا السطر بالتحديد
Private Function ComfirmCustomer(ByVal Name As String) As String
كذلك داخل الـ Function تلاحظ الكلمة Return وهي كلمة يراد بها القيمة العائدة للمنادي لهذا الـ Function
هي في المثال السابق كُتبت بهذا الشكل في الشرط If statement
فإن لم يكن اسم الزبون داخل قاعدة البيانات سترجع القيمة NoRecord
غير ذلك ستم إسترجاع اسم الزبون عن طريق الممرر الخارجي Output Parameter
من الـ storedProcedure بهذا الشكل Return cmd.Parameters("@critera").Value.ToString
If NameReturn Is Nothing Then
Return "NoRecord"
Exit Function
Else
Return cmd.Parameters("@critera").Value.ToString
End Ifو يتم مناداة هذا الـ Function و إختبار القيمة الراجعة بهذا الشكل .
Dim Name As String Name = ComfirmCustomer(txtCustomerName.Text) If Name <> "NoRecord" Then 'Do what Ever End if
أما الـ Sub فهو عندما لا تحتاج لقيمة عائدة لانك ببساطة لا تحتاج للإختبار أصلاً مثال ذلك
أنك تريد أن تفرغ محتوى عناصر من نوع TextBoxes ويكون كالتالي
Private Sub ClearTextBoxes() Dim ctrl As Control For Each ctrl In Me.Controls Try If TypeOf ctrl Is TextBox Then ctrl.Text = "" End If Catch ex As Exception MessageBox.Show(ex.Message) End Try Next End Sub
ويتم إستدعائه بهذا الشكل
Private Sub btnReset_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnReset.Click ClearTextBoxes() End Sub
ففي هذه الحالة أنت لا تحتاج هل تم إفراغ العناصر أم لا لإن العمل حاصلٌ لا محاله ولأن عدم حصوله لا يخلق مشكلة جوهرية
بل ثانوية فقط .
و أما عن Shared فهي مشاركة عناصر Class دون الحاجة لإستنساخ هذا الـ Class مثال ذلك
أنك تريد حساب عمر الطالب سيكون بهذا الشكل
Public Class Calculation Public Shared Function CalculateAge(ByVal birthday As DateTime) As Integer If Not IsDate(birthday) Then Exit Function Dim bd As DateTime Try ' Birthday this year bd = New DateTime(DateTime.Today.Year, birthday.Month, birthday.Day) Catch ' no valid date, must be a leap year Then.... ' set birthday one day futher in time. birthday = birthday.AddDays(1) bd = New DateTime(DateTime.Today.Year, birthday.Month, birthday.Day) End Try Dim age As Integer = DateTime.Today.Year - birthday.Year If (DateTime.Today < bd) Then age -= 1 Return age End Function Public Function CalculateAge1(ByVal birthday As DateTime) As Integer If Not IsDate(birthday) Then Exit Function Dim bd As DateTime Try ' Birthday this year bd = New DateTime(DateTime.Today.Year, birthday.Month, birthday.Day) Catch ' no valid date, must be a leap year Then.... ' set birthday one day futher in time. birthday = birthday.AddDays(1) bd = New DateTime(DateTime.Today.Year, birthday.Month, birthday.Day) End Try Dim age As Integer = DateTime.Today.Year - birthday.Year If (DateTime.Today < bd) Then age -= 1 Return age End Function End Class
الان لنفترض أن هذا الـ Class Calculation مدرج ضمن مشروعك
كل الذي عليك أن تكتب التالي
Dim x As Integer = Calculation.CalculateAge(DTPAge.Value)
تلاحظ أنني لم أقم بستنساخ عنصر من الـ Calculation Class لان الـ CalculateAge Function من نوع Shared
أما الوظيفة الثانية وهي Function CalculateAge1 لإستدعائها يحب أن تقوم بعملية
الإستنساخ أو ما تعرف ب Instantiation وهي بإستخدام المعامل أو الكلمة المحجوزة New
اي لإستدعاء الوظيفة Function CalculateAge1 يكون بهذا الشكل
Dim myCal As New Calculation Dim x As Integer = myCal.CalculateAge1(DTPAge.Value)
من الأشياء الضرورية في الـ Shared هو أن المتغيرات المستخدمة فيه يجب أن تكون من نوع Dim
وتكون بلا شك في داخلة .
اي إستفسار نحنُ في الخدمة
هذا والله أعلى و أعلم
السلام عليكم
في المثال يتضح المقال
بارك الله فيك يا اخي الغملاسي
افادتني شكرا لك
هذا الموضوع مغلق.