307. Non zero based arrays

כולנו מכירים מערכים בC#.

אני אישית התרגלתי שמערכים בד”כ מתחילים מתא מספר אפס בשפות תכנות, ולמעשה אני חושב שלא פגשתי במערכים שהם לא Zero based, מאז שתכנתתי בפסקל.

מסתבר שבC# מערכים יכולים להתחיל גם מאינדקס שאינו 0. איך זה אפשרי? הרי אנחנו מכירים שהדרך של לאתחל מערך היא בצורה הזאת:

1
int[] myArray = new int[6];

איפה אפשר בדיוק להכניס את הlower bound של המערך כאן?

אז זהו, שיש עוד דרך לאתחל מערכים בFramework, והיא ע"י הפונקציה Array.CreateInstance.

זה נראה בערך ככה:

1
int[] myArray = (int[]) Array.CreateInstance(typeof (int), 6);

אלא שיש Overloadים שמאפשרים לנו לציין את הLower bound:

1
Array myArray = Array.CreateInstance(typeof (int), new[] {6}, new[] {2});

אם ננסה לעשות הסבה למערך שהוא Typed safe, לא נצליח:

1
int[] myArray = (int[]) Array.CreateInstance(typeof (int), new[] {6}, new[] {2});

נקבל את הException הבא:

Unable to cast object of type ‘System.Int32[*]’ to type ‘System.Int32[]’.

לא כל כך ברור מהו הטיפוס הזה של המערך.

נוכל לגשת ע"י שימוש בפונקציות של Array, שהן לא Typed safe (ומבצעות boxing):

1
2
3
4
Array myArray = Array.CreateInstance(typeof (int), new[] {6}, new[] {2});
myArray.SetValue(3, 7);
Console.WriteLine(myArray.GetValue(7)); // 3

מה שאפילו יותר מוזר, זה שאם ניצור בעזרת פונקציה זו מערך רב מימדי, דווקא כן נוכל לבצע אליו הסבה!

1
2
3
4
int[,] myMatrix =
(int[,]) Array.CreateInstance(typeof (int), new[] {6, 8}, new[] {2, 3});
myMatrix[7, 10] = 3;

האמת שלא כל כך ברור מה הולך כאן, ואם למישהו יש הסבר, אני אשמח לשמוע.

בכל מקרה הדבר בעיקר מעניין, אבל לא הייתי ממליץ להשתמש בזה, מאחר ורובנו רגילים כי מערכים הם Zero based ולכן אם מישהו יתקל בקוד כזה הוא עשוי לשבור את הראש מה בדיוק קורה פה.

יום לא Zero-based טוב!

שתף