سلام علیکم برادران و آبجیان ارجمند!!!
(ببخشید کمی زیاد کمی زیاد است، ولی لطفاَ با دقت بخوانید، برای با خسته نشدن حضار جسارت کرده و متن را از طنزهای لطیفی وراثت گرفته ام!)
خوبید یا بهترید؟! دشمنی تان با VB تمام نشده؟! باشه ایرادی نداره! ما سعی میکنیم یک کمیسون دات نتی، وراثتی، صفر و یکی، جهت آشتی ملی و گفتمان دات نتی (یک چیزی تو مایه های گفتگوی تمدن ها!) تشکیل بدیم!!!!!!!!!! یا حداقل به آن ادامه بدیم!
ادامه گفتمان دات نتی!
قابلیت Iterators چیزی بجز پشتیبانی راحت از رابطهای IEnumerator و IEnumerable نیست (و البته دوقولوهای Generic شان).
قابلیت Iterators در اصل یک نوع پارتی بازی #C برای پیاده سازی دو رابط فوق است.
باز هم دوستان دچار سوء تفاهم نشوند، نمیخواهم چیزی از ارزش این قابلیت کم کنم ولی آیا برای پیاده سازی هر واسطی باید دستور خاصی وجود داشته باشد؟ یا شاید #C کارها برای پیاده سازی هر واسطی دستور هلو وار و جدید و مخصوصی میخواهند؟(معرفت بگذارید به من پیرمرد کمتر ناسزا بگید!) آیا #C کارها که دستور Mid و CInt، CLng، CDbl، With، و... را ندارد لنگ مانده اند؟ یا شاید VB کارها که دستور yield را ندارند لنگ مانده اند؟!
پشتیبانی از دو رابط فوق را میتوان بدون پارتی بازی برای آنها و صرفاَ با قوانین اصلی وراثت و پلیمورفیزم مثل دیگر رابط ها انجام داد.
برای درک کامل مطلب به کدهای زیر که شامل پیاده سازی رابطهای فوق در #C و VB و استفاده از آنها هستند دقت کنید.
بدیهی است که به علت پارتی بازی #C از دو رابط فوق کد تعریف به شدت کاهش یافته (3+1 متد تعریف اجباری وجود دارد که باید تعریف شوند) ولی کد استفاده کاملاً یکسان است و دارای یک مقدار کدنویسی ثابت هستند، این افزایش کد هم در هیچ یک از رابطهای دیگر وجود دیده نمیشود.
البته راه حل دیگری هم در VB وجود دارد، که بسیار کم کد است و به درستی و سرعت کار میکند ولی از نظر زیرساختی نمیتوان آن را معادل Iterators به حساب آورد ولی همان کار را انجام میدهد
//C# declare
--------------------------------------------------
public class SampleClass
{
public static System.Collections.IEnumerable SampleIterator(int maxvalue)
{
for (int iCounter = 0; iCounter <= maxvalue; iCounter++)
{
yield return iCounter;
}
}
}
//C# using
--------------------------------------------------
foreach (int i in SampleClass.SampleIterator(7))
{
//Any code.
}
'VB.Net declare
--------------------------------------------------
Public Class SampleClass
Private Class IEnumerableClass
Implements System.Collections.IEnumerator
Implements System.Collections.IEnumerable
Private iCounter As Integer = -1
Private ReadOnly maxvalue As Integer
Public Sub New(ByVal maxvalue As Integer)
MyBase.New()
Me.maxvalue = maxvalue
End Sub
Private ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
Get
Return Me.iCounter
End Get
End Property
Private Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
Me.iCounter += 1
Return (Me.iCounter <= Me.maxvalue)
End Function
Private Sub Reset() Implements System.Collections.IEnumerator.Reset
Me.iCounter = -1
End Sub
Private Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return Me
End Function
End Class
Public Shared Function SampleIterator(ByVal maxvalue As Integer) As System.Collections.IEnumerable
Return New IEnumerableClass(maxvalue)
End Function
End Class
//VB.Net using
--------------------------------------------------
For Each i As Integer In SampleClass.SampleIterator(7)
'Any Code.
Next
راه حل با کد کمتر که همان کار را میکند ولی معادل فنی و زیر ساختی Iterators نیست.
'VB.Net declare
--------------------------------------------------
Public Class SampleClass
Public Shared Function SampleIterator(ByVal maxvalue As Integer) As System.Collections.IEnumerable
Dim ret As New System.Collections.ArrayList
For iCounter As Integer = 0 To maxvalue
ret.Add(iCounter)
Next
Return ret
End Function
End Class
//VB.Net using
--------------------------------------------------
For Each i As Integer In SampleClass.SampleIterator(7)
'Any Code.
Next
راستی بحث به جای جالبی کشید! خیلی جالب! از دوستانت عزیز بابت پافشاری و یادآوری آن فراوان فراوان تشکر میکنم!؟!؟!؟!؟ (خاصه دوست عزیز PC2st.ir و استاد arsp_2004 ! با اجازه دوستان و خارج از شوخی، من واقعاً ایشان را به عنوان مرجع ناطق #C قبول دارم.)
همان طور که Form1.Show کد نویسی را کم میکند، yield هم کد نویسی را کم میکند و همان طور که دستور کثیف Form1.Show یک VB کار تازه کار را از فهم عمیق و درک کامل اعمالی که در پسضمینه انجام میشود دور میکند، دستور غیر کثیف yield هم همین بلا را بر سر #C کارهای غیر تمام حرفه ای در می آورد! میدانید چرا؟ مطمئناً و بدن شک بیش از 85 درصدر #C کارهای همینجا نمیدانند و yield را معجزه #C و چیز عجیب و خارق العاده ای تصور میکنند ولی در زیر ساخت همان کاری انجام میشود که من در نمونه کد اول با VB.Net انجام دادم (البته با الگوریتمی متفاوت)، و یک کلاسس کمکی توسط #C ساخته میشود که دو رابط فوق را تعریف میکند.
دوستانی هم که میدانند، حتماً مثل من هنوز کجکاو بوده اند و از خودشان پرسیده اند که چگونه #C مقید به OOP در یک تابع یک رابط را برمیگرداند که باید در یک نوع ساختار تعریف شده باشد در حالی که خروجی return تابع اصلاً ربطی به خروجی نهایی ندارد و مثلاَ میتواند یک Integer باشد.
پس این Form1.Show ما به yield شما در! البته مجبورم مجدداَ به گفته همان کاربر قبلی صحه بگذارم و اعتراف کنم که Form1.Show کثیف تر از yield است. ولی بحرحال این به آن در!
راستی دوستان شفیق #C کار به اون قابلیت های کوچک ولی مفید که گفتم بعضی، بعضی، بعضی #C کارها فکر میکنند فقط در زبان آنها وجود دارد، دستور Continue را هم برای استفاده در حلقه ها اضافه کنند.
لطفاَ در مورد متدهای بی نامی مثالی با کدنویسی بزنید، البته سعی میکنم در اولین وقت خالی خودم دنبالش بگردم.
موفق و پیروز و کمی کنجکاو باشید جوانان، دات نت کار! و نگذارید تعصب شما را از حقیقت دور کند.