What is a String[*] and how do I cast it?

前端 未结 2 929
说谎
说谎 2021-01-21 04:57

I\'m currently in the unfortunate position of having to call a VBA macro from C#, via the COM Interop. The macro returns an array of strings and looks something like:

         


        
相关标签:
2条回答
  • 2021-01-21 05:26

    Your code was

    var result = (string[])xlApp.Run("Foo", ... missing args ...);
    

    As you have pointed out there is different behaviour with a 1-based array, with a zero-based array in VB your code does work.

    You can get at the data like this

    var result = (Array)xlApp.Run("Foo", ... missing args ...);
    
    var stringsResult = result.Cast<string>[];
    

    This gives you an IEnumerable of string

    0 讨论(0)
  • 2021-01-21 05:26

    .NET supports such arrays (that have lower bound different from 0), you can create one using such snippet:

    Array arr = Array.CreateInstance(typeof(string), new int[] { 5 }, new int[] {1});

    The simplest way to convert such array to string[] is (although, it's copying data, on the other hands, those are just references, so if your arrays aren't too long, you won't get huge perf hit):

    string[] x = new string[5];
    Array.Copy(arr, 1, x, 0, 5);
    

    Edit: Or using more general approach:

    string[] x = new string[arr.GetLength(0)];
    Array.Copy(arr, arr.GetLowerBound(0), x, 0, arr.GetLength(0));
    

    Edit2: It also looks like casting arrays with lowerbounds != 0 works for fine, if there are more than 1 dimension, you can read more here, where Jon Skeet seems to answer why that happens.

    Edit3: To make response less ambiguous, following djna's comments. This is how you could obtain string[] out of object returned by a method, that can't be cast to string[] directly, because it has lowerBound != 0:

    Array arr = (Array)xlApp.Run("Foo", ... missing args ...); //Here I assume that .Run() method is returning object, or something that has to be casted to Array.
    string[] result = new string[arr.GetLength(0)];
    Array.Copy(arr, arr.GetLowerBound(0), result, 0, arr.GetLength(0)); // Here data is copied, but only references in this scenario
    
    0 讨论(0)
提交回复
热议问题