【问题标题】:How to cast System.Object[*] to System.Object[] II如何将 System.Object[*] 转换为 System.Object[] II
【发布时间】:2014-04-29 14:04:29
【问题描述】:

我遇到了类似 Cheva 在他的问题中遇到的问题:

How to cast System.Object[*] to System.Object[]

我通过 COM 互操作功能使用外部库 (Reuters EIKON API)。

提交请求后,对象会更新,其数据成员也会更新。对象目录为 Data 成员显示了这一点:

public virtual dynamic Data { get; }

在debug模式下,我可以看到,提交请求后,DataStatus变成了dataset_full,Data成员实际上已经被填充了。

数据成员显示为 {object[1..31]},我可以从调试下拉菜单中看到,这个集合中实际上有一个字符串。

我的问题是我无法访问这个对象。我可以将其转换为 object[]string[] 或任何其他内容。我什至无法找出它的类型。

它总是说System.Object[*] 不能转换为System.Object[]

如果我尝试使用 .Type() 找出类型,我会得到“System.Reflection.TargetInvocationException”。我什至无法访问它的长度,这也给了我错误

System.InvalidCastException -> Object of Type "System.Object[*]" cannot be cast to type "System.Object[]"

有人见过类似的错误吗?

【问题讨论】:

  • 您能否附上您用于投射的代码,以便我们查看您的尝试?
  • 您是否尝试将动态投射到对象[]?
  • 它是一个下界不为 0 的不一致数组。在 COM 互操作中并不少见,从 1 开始是相当典型的。您只能转换为(数组)。并使用它的 GetLowerBound() 方法知道从哪里开始索引,GetUpperBound() 知道在哪里停止,GetValue() 来读取一个元素。
  • 我在这里工作 VSTO 时遇到了完全相同的问题。 Excel.Filter.Criteria1 是动态的,过滤器返回一个“object []”,但行为与您所说的完全一样。不能循环,没有方法、属性、字段、成员,什么都没有。一旦动态拥有它,它就不能存储在另一个动态对象上。明智地使用你的 1 枪!

标签: c# casting com-interop


【解决方案1】:

System.Object[*] 是一个 System.Array,它是一维的,但没有从 0 开始索引。它在 C# 中没有得到很好的支持,因为 C# 使用从 0 开始的索引。

System.Object[*] 不是 object[],因此您不能转换为该类型。

你可以使用:

var dataAsArray = (Array)Data;

var dataAsNonGenericIList = (IList)Data;

那么你就可以通过它foreach了。

或者您可以按索引访问单个条目,如下所示:

object first = dataAsArray.GetValue(1);

分别:

object first = dataAsNonGenericIList[1];

您需要计算出上限和下限(dataAsArray.GetLowerBound(0)dataAsArray.GetUpperBound(0)),但在您的情况下,下限似乎是1

您可以按通常的方式转换为string,如果您希望它每次都是字符串,则可以转换为(string)first,或者如果您想支持其他对象,则可以转换为first as string(然后检查是否为空)。


如果您想将“奇怪”数组复制到索引为 0 的数组,请参阅标题中没有数字 II 的链接线程。当然,索引会改变。例如object[] newArray = new object[dataAsArray.Length]; dataAsArray.CopyTo(newArray, 0);


很多稍后编辑:

除了我上面写的内容之外,当实际类型为 System.Object[*] 时,与 C# dynamic 功能一起使用的运行时绑定器中存在一个错误。这也可以从上面的问题中推断出来。举个例子(我创建的数组排名第一,唯一维度的长度是31,该维度的下限是1(即非零索引)):

dynamic Data = Array.CreateInstance(typeof(object), new[] { 31, }, new[] { 1, });
dynamic t = Data.GetType(); // throws!
dynamic s = Data.ToString(); // throws!

在任何一种情况下都会抛出InvalidCastException

无法将“System.Object[*]”类型的对象转换为“System.Object[]”类型。

这是一个错误,我会说。成员存在,我没有要求强制转换为那种类型,我要求对存在的成员进行后期绑定。

当我直接从dynamic 转换为ArrayIList 时,运行时也会出现同样的错误,就像我在上面的原始答案中所做的那样。

您可以通过以下方式解决此错误:

var dataAsArray = (Array)(object)Data;

和:

var dataAsNonGenericIList = (IList)(object)Data;

使用后期绑定(即来自dynamic)投射到object 似乎不受该错误的影响。下一个演员阵容,从objectArray(或IList),是一个没有dynamic 魔法的普通向下演员,当然可以。

有了这个,我的答案变得有用(多年后)。

我只是意识到an answer by RoadBump in a linked thread 也提供了此信息,所以请为该答案投票。

【讨论】:

  • 说得好,奇怪的数组。感谢您的启发,但问题是它们不包含任何方法、成员、字段,就像我的情况一样,仅包含“字符串”列表。不幸的是,您甚至无法循环通过,您的建议将不起作用。 : (
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 2015-02-25
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多