简体   繁体   中英

C#: Is there a way to resize an array of unknown type using reflection?

My users pass me an array of some type, say int[] or string[]. I can easily query the types of the elements via GetElementType, and I can find out how long the array was when it was passed to me via GetRank, GetLength, etc.

The arrays are passed in a params list, so visualize code like this:

    public void Resizer(params object[] objs)
    {
        foreach (object o in objs)
            Array.Resize(ref o, 3);
    }

What I would like to do is the converse of the Get methods that are available and that do work: I want to resize the array that was passed to me, setting the length to some other length (like 3 in this silly example).

I'm doing this because in my setting the array will contain data received from a set of cloud computing servers and we can't know how many will respond in advance, hence can't preallocate the array to have the right length. Ideally, in fact, my user passes in an array of length 0, and I pass back an array of length n, signifying that I got n replies from the servers that were queries.

I can't do this with Array.Resize(ref T, int) because I don't know T at compile time.

Is there a way to pull this off?

This should work:

static void Resize(ref Array array, int newSize) {        
    Type elementType = array.GetType().GetElementType();
    Array newArray = Array.CreateInstance(elementType, newSize);
    Array.Copy(array, newArray, Math.Min(array.Length, newArray.Length));
    array = newArray;
}

Why not just create a new array of whichever type you need that is the size that you want? Then populate it from the array you want to resize, setting non existent values to some default.

万一有人好奇,我最终将代码切换为使用List

I agree with the comments that you should be using List(Of T), but if you want to copy your array into a new array of the same type, you could do something like the following.

// Your passed in array.
object[] objs = new object[5] {1,2,3,4,5};

// Create an array of the same type.
Array a = Array.CreateInstance(objs[0].GetType(), objs.Length+3);

// Copy in values.
objs.CopyTo(a,0);

I guess I'll just switch to using Lists, but this is a shame; the code will be quite a bit messier looking and since my users are basically at the level of first-semester ugrads, each little thing will make their lives less good. But I'm suspecting that you folks don't see a way to do this either. Oh well....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM