Reading your update turns this into a different question. Unlike PHP, C# is serious about types, so you can't just stuff things into variables or array slots. You have to explicitly declare that you want a multi-dimensional array. In C# arrays are not as flexible as in PHP. In PHP, you can use anything as a key. In C#, you have to use a different type entirely (which is actually what PHP is doing behind the scenes as all arrays in PHP are hash tables internally).
I'm going to make another assumption, which is that part of this code is in a function that fills in attributes for a single id, and that your result variable is actually shared across multiple calls of this function. I can't see how your code would make sense otherwise.
// this is probably shared
Dictionary<int, List<string>> result = new Dictionary<int, List<string>>();
// perhaps this next bit is in a function that gets the attributes for a given tag
int id = Convert.ToInt32(textReader.GetAttribute("id"));
result[id] = new List<string>();
foreach(string attr in attrs) {
result[id].Add(textReader.GetAttribute(attr));
}
What we have here is a hash of integers and growable arrays (C# calls these dictionaries). That is, the outer structure is equivalent to a PHP array that maps integers to subarrays. The subarrays are essentially the same, except we use List in C# because it can grow -- we don't have to allocate exactly the right number of elements when we create it. You could do that, but it might be extra work. I'll leave it as an exercise to the OP to implement it that way.
Just in case you aren't aware of what Dictionary<int, List<string>> means, you should read up on generics in C#. Translated to English, it basically says "dictionary (that is, hash table) with keys that are int and values that are List<string>, that is, list of values that are string". Note also that each list in the dictionary has to be initialized separately, which is why I have the line just above the foreach. PHP auto-reifies things, but C# does not.