.NET Forum / .NET Framework / CLR / February 2004
get type of array items?
|
|
Thread rating:  |
boxboy - 15 Feb 2004 02:41 GMT I am trying to write a utility method/function in c# to resize an array, the problem I have encountered is how to safely get the Type of the items in the array, even when the array is empty.
Here is how the code I wrote:
public static Array Redim(Array a, int length)
{ Type type = a.GetValue(0).GetType(); Array copy = Array.CreateInstance(type, length); Array.Copy(a, 0, copy, 0, Math.Min(a.Length, length)); return copy; }
This code works fine, but as you might see, the problem arises when an array of length zero is passed in.
The line:
Type type = a.GetValue(0).GetType();
Will cause an exception as the index 0 is outside the bounds of an empty array. Also, please note ...
If a is:
string[] a = {};
Then:
a.GetType();
Returns:
System.String[]
Which is not the same as:
System.String
So the question is, how is it possible under all circumstances to safely get the Type of the items in array?
Thanks in advance for any help.
Justin Rogers - 15 Feb 2004 03:06 GMT If the array is empty, since you've already cast it down to an Array, both Type.IsArray will return false, and Type.GetElementType will return null. You won't be able to get the type of a zero length array. What you might do is:
public static Array Redim(Array a, Type elementType, int length) { }
string[] myStrings = new string[] {}; Redim(myStrings, myStrings.GetType().GetElementType(), newLength);
Even the VB Redim statement loses the ability to re-dimension an array once it has been cast down to an actual System.Array since System.Array is nothing more than an object. You can probably get the type name based on the type name of the Array itself. Simply chop off the array-like naming conventions from the end, but that sounds dangerous to me. Redim will be a lot easier when you get the ability to use generics.
 Signature Justin Rogers DigiTec Web Consultants, LLC. Blog: http://weblogs.asp.net/justin_rogers
> I am trying to write a utility method/function in c# to resize an array, the > problem I have encountered is how to safely get the Type of the items in the [quoted text clipped - 41 lines] > > Thanks in advance for any help. boxboy - 15 Feb 2004 07:17 GMT > If the array is empty, since you've already cast it down to an Array, both > Type.IsArray will return false, and Type.GetElementType will return null. You [quoted text clipped - 12 lines] > end, but that sounds dangerous to me. Redim will be a lot easier when you get > the ability to use generics. Interesting.
I hadn't noticed the GetElementType method before and decided to try it out both with filled and empty arrays. The following code works fine:
public static Array Redim(Array a, int length) { Type type = a.GetType().GetElementType(); Array copy = Array.CreateInstance(type, length); Array.Copy(a, 0, copy, 0, Math.Min(a.Length, length)); return copy; }
Test:
string[] s = (string[])Redim(Array.CreateInstance(typeof(string), 0), 2); s[0] = "hello"; s[1] = "world"; textBox.Text = s;
Also works with 'new string[] {};' in place of CreateInstance. It would seem that the GetElementType is returing System.String instead of null as you suggested.
Much thanks though, as my problem is now solved.
Jon Skeet [C# MVP] - 15 Feb 2004 08:07 GMT > If the array is empty, since you've already cast it down to an Array, both > Type.IsArray will return false, and Type.GetElementType will return null. No it won't. Casting a reference to another type doesn't change the actual object referred to at all. For instance:
using System;
public class Test { static void Main() { Array foo = new string[0]; Console.WriteLine (foo.GetType().IsArray); Console.WriteLine (foo.GetType().GetElementType()); } }
prints out
True System.String.
> You won't be able to get the type of a zero length array. Again, not true. See above.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too
Justin Rogers - 16 Feb 2004 01:01 GMT Well, then straight from the documentation on System.Array:
Type.IsArray and Type.GetElementType might not return the expected results with Array because if an array is cast to the type Array, the result is an object, not an array. That is, typeof(System.Array).IsArray returns false, and typeof(System.Array).GetElementType returns a null reference (Nothing in Visual Basic).
Unlike most classes, Array provides the CreateInstance method, instead of public constructors, to allow for late bound access.
The Array.Copy method copies elements not only between arrays of the same type but also between standard arrays of different types; it handles type casting automatically.
Don't know exactly what to make of that. Possibly a mis-print. However, there have been instances, were the documentation is correct. However, it may have been correct pre V1, since that is when I have the error logs demonstrating the problem.
 Signature Justin Rogers DigiTec Web Consultants, LLC. Blog: http://weblogs.asp.net/justin_rogers
> > If the array is empty, since you've already cast it down to an Array, both > > Type.IsArray will return false, and Type.GetElementType will return null. [quoted text clipped - 22 lines] > > Again, not true. See above. Jon Skeet [C# MVP] - 16 Feb 2004 11:09 GMT > Well, then straight from the documentation on System.Array: > [quoted text clipped - 3 lines] > typeof(System.Array).GetElementType returns a null reference (Nothing in Visual > Basic). <snip>
> Don't know exactly what to make of that. Possibly a mis-print. However, there > have been instances, were the documentation is correct. However, it may have > been correct pre V1, since that is when I have the error logs demonstrating the > problem. That's very odd. It makes sense to me for typeof(System.Array).IsArray to return false, and typeof(System.Array).GetElementType to return null, because Array itself isn't an array, it's just the base type for all arrays. This is similar to how ValueType itself is a reference type. That said, "casting" an array to Array doesn't change the object (the array) itself, so that bit of documentation is just bizarre, IMO.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too
Kit George (MSFT) - 23 Feb 2004 18:19 GMT All, we are slightly modifying our docs based on this thread, thanks for the input. This basically comes down to a standard for what IsArray means. We require that you have a specific instance of, or a more solid form of an Array, for IsArray to be true. THis is not a cavernous pit here, we do the same thing with ValueTypes, and we do the same thing for Enums.
Thanks, Kit
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|