返回应用程序的类型.在特殊情况下求值

本文关键字:在特殊情况下 类型 应用程序 返回 | 更新日期: 2023-09-27 18:13:18

我正试图在c#中编写一个方法,该方法将给定Excel工作簿中指定范围的名称,检索该范围内的值。我希望它能工作,即使命名的范围不是一个纯引用的范围(例如=Sheet1!A1:A10),而是像={1,2,3,4,5}=OFFSET(Sheet1!A1:A10,3)

我正在做以下事情:

Excel.Application xl = ...;
Excel.Name name = ...;
object value = xl.Evaluate(name.Value);
// if it's a range, turn it into an object[] or object[,]
if (value is Excel.Range) value = ((Excel.Range)value).Value2;
if (value is object[]) {
    // do stuff
} else if (value is object[,]) {
    // do slightly different stuff
}

我曾认为具有={1,2,3,4,5}等值的命名范围将作为object[]object[,]出现,但事实并非如此。value.GetType()只是报告System.__ComObject(编辑:现在我得到System.Object[*],并没有能够重现System.__ComObject -但它仍然没有转换到object[]),我还没有能够进一步缩小范围。

我应该将value转换为什么类型?

以下是一些测试代码和输出。这可能是一个更简单的问题:"System.Object[*]到底是什么,谷歌的变幻莫测不允许我搜索。" 代码:

using System;
using Excel = Microsoft.Office.Interop.Excel;
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Excel.Application xl = new Excel.Application();
            object value = xl.Evaluate("={1,2,3,4,5}");
            Console.WriteLine(value);
            Console.WriteLine(value is object[]);
            Console.WriteLine(value.GetType());
            Console.ReadLine();
            xl.Quit();
        }
    }
}
输出:

系统。对象[*]

系统。对象[*]

edit2:如果我代替评估"={1;2;3;4;5}",那么我得到一个object[,]。嗯。

返回应用程序的类型.在特殊情况下求值

我认为这是因为Excel创建的数组不是基于0的,而是基于1的,你可以这样转换它:

object[] ints = ((Array)value).ToArray<object>();

使用这个辅助方法扩展:

public static T[] ToArray<T>(this Array array)
{
    if (array == null)
        return null;
    if (array.Rank != 1)
        throw new NotSupportedException();
    var newArray = new T[array.GetLength(0)];
    var lb = array.GetLowerBound(0);
    for (int i = 0; i < newArray.Length; i++)
    {
        newArray[i] = (T)array.GetValue(i + lb);
    }
    return newArray;
}

如果你使用。net 4,有可能将Evaluate的返回类型定义为dynamic。用下面的代码:

dynamic value = xl.Evaluate("={1,2,3,4,5}"); // or var instead of dynamic

你将得到一个System.InvalidCastException: Unable to cast object of type 'System.Object[*]' to type 'System.Object[] ',因为新的。net 4互操作层将尝试自动创建一个标准数组。因此,您需要这样做(就像您在代码中所做的那样):

object value = xl.Evaluate("={1,2,3,4,5}");
object[] ints = ((Array)value).ToArray<object>();