【问题标题】:Unable To Cast object type 'System.String[*]' to type 'System.String[]'无法将对象类型“System.String[*]”转换为“System.String[]”
【发布时间】:2012-09-07 03:15:32
【问题描述】:

大家好,我对 C# .NET 中的代码有疑问,我正在使用 DLL 连接到 OPC 服务器,该 DLL 在 VB.NET 项目中使用并且完全没有问题。

我正在尝试在 ListBox 中显示可用服务器的列表,VB.NET 中使用的代码(并且有效)是这个:

Dim AllOPCServers As Object
AllOPCServers = AnOPCServer.GetOPCServers

' Load the list returned into the List box for user selection
Dim i As Short
For i = LBound(AllOPCServers) To UBound(AllOPCServers)
    AvailableOPCServerList.Items.Add(AllOPCServers(i))
Next i

我写这个是为了在 C# 应用程序中使用

try
{
    var _listOPCServer = _OPCServer.GetOPCServers();
    foreach(var i in _listOPCServer)
    {
        string serverName = (string)i;
        listServers.Items.Add(serverName);
    }             
}
catch (Exception exc)
{
    lstMsg.Items.Add(DateTime.Now + " Error al Obtener Lista de OPC's: " + exc.Message);
}

在本地选项卡上的调试模式下显示:

_listOPCServer | {字符串[1..2]} |动态 {string[]} |

[1]        |  "Server01"    | string  
[2]        |  "Server02"    | string

更新:

我在“foreach(var i in _listOPCServer)”行中收到错误

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

这是真正的错误。

我确定我做错了什么,有人可以帮助我吗?

【问题讨论】:

  • 这里是 similar 案例的最小复制:(string[])(new string[0,0]),虽然我不知道如何产生确切的消息.. 在任何情况下,请张贴 真正的错误消息(复制和粘贴)以避免可能的错误。
  • 你在哪一行得到错误?我看不出你想将_listOPCServer 投射到什么地方。
  • @pst 这是我无法将对象类型“System.Sting[*]”输入“System.String[]”的错误
  • @DStanley 我在 foreach(var i in _listOPCServer) 行中得到错误
  • @DStanley 哈哈抱歉,拼写错误,是字符串,让我更正一下

标签: c# .net visual-studio-2010 casting opc


【解决方案1】:

好的,我找到了解决这个问题的方法,这只是你建议的一个模式

 Array _listOPCServer = (Array)(object)_OPCServer.GetOPCServers();               

            foreach(object i in _listOPCServer)
            {
                string serverName = (string)i;
                listServers.Items.Add(serverName);
            }             

我只在声明中添加了(对象)并且工作正常,现在我可以按照我想要的方式显示服务器列表

或者也这样做

Array _listOPCServer = (Array)(object)_OPCServer.GetOPCServers();               

            foreach(object i in _listOPCServer)
            {
                listServers.Items.Add(i);
            }

再次感谢您的帮助和时间!

【讨论】:

    【解决方案2】:

    VB.NET 在处理不一致的数组类型方面更加精明。不要犹豫,使用它,.NET 使语言之间的互操作变得容易。

    问题在于 OPC 是基于 COM 的标准。您正在使用的服务器正在返回一个 SAFEARRAY,其下限不一致,第一个索引是 1。不是 0。在 COM 中并不罕见,在 0 和 1 之间选择作为第一个数组索引就像端序问题或争论是否番茄是一种水果或蔬菜(它是一种水果。小端序是正确的蔬菜)。

    但是,0 作为下限是 C# 在处理一维数组时所坚持的。它需要一个“向量”,一种独特的数组类型,它始终具有一个下限为 0 的维度。在 .NET 运行时中进行了大量优化。你得到的不匹配,所以被映射到一个 one 维度的 multi-dimensional 数组。不是可以用 C# 语言表达的数组类型。

    可以在 C# 中破解它,但您必须明确使用 Array 类型。像这样的东西,为了清楚起见:

    Array servers = (Array)_OPCServer.GetOPCServers();
    int first = servers.GetLowerBound(0);
    int last = servers.GetUpperBound(0);
    for (int ix = first; ix <= last; ++ix) {
        var elem = (string)servers.GetValue(ix);
        // etc..
    }
    

    【讨论】:

    • 不应该foreach 仍然在非零基数组上工作吗?演员们在哪里演出?
    • 其实不知道。我从来没有想过尝试它,数组实现IEnumerable&lt;T&gt; 的错觉必然会落在这种代码上。就试一试吧。演员表很明显,Array.GetValue() 返回一个 Object。
    • 我的意思是从System.Sting[*]System.String[] 的演员阵容,OP 获得了例外。
    • 好吧,不,这不可能。我回答的任期。向量与一维的多维数组不兼容。
    • 我明白;我不明白的是为什么编译器试图转换为string[]。我已经根据我的猜测添加了答案。
    【解决方案3】:

    虽然 Hans 在区分从零开始的数组和非从零开始的数组之间的区别是正确的,但我仍然不明白您为什么会遇到这种异常。

    我的猜测是您将_OPCServer 声明为dynamic,这会将类型绑定推迟到运行时。因此_listOPCServer 也是dynamic

    由于您正在遍历数组并提取 strings,编译器可能试图将对象转换为 string[],正如 Hans 指出的那样,这是无效的。

    您应该能够将_listOPCServer 转换为Array 并照原样使用foreach

    Array _listOPCServer = (Array)(_OPCServer.GetOPCServers());
    foreach(var i in _listOPCServer)
    {
        // etc.
    

    【讨论】:

    • 您好,感谢您花时间回答这个问题,但我也尝试了您推荐的方式,但仍然在 Array _listOPCServer = (Array)(_OPCServer.GetOPCServers()) 行中遇到相同的错误;
    • 我遇到同样的错误我会用一些截图更新帖子
    猜你喜欢
    • 2014-03-14
    • 2017-11-24
    • 2019-12-07
    • 1970-01-01
    • 2021-04-26
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多