@ugotowany_kamien: bo w tym drugim przypadku masz deklarację i przypisanie jednocześnie. W pierwszym przypadku masz oddzielnie deklarację i oddzielnie przypisanie wartości i tutaj może np. polecieć IndexOutOfRangeException tylko coś go musi rzucić (metoda albo instrukcja throw), a że obiekt na tym etapie jeszcze nie istnieje w pełni (musiałoby zakończyć się wykonywanie konstruktora) to nie ma na dobrą sprawę co go rzucić i skąd polecieć. Druga rzecz, że gdyby to było
string[] tab = new string[3];
tab[0] = "a";
tab[1] = "b";
tab[2] = "c";
tab[3]