无法转换对象类型'System.String [*]'以键入'System.String []'

时间:2012-09-13 23:43:37

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

大家好我在C#.NET中遇到代码问题,我正在使用DLL连接到OPC服务器上的VB.NET项目中使用的DLL并没有任何问题。

我正在尝试在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 | {string [1..2]} | dynamic {string []} |

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

更新

我得到的错误是“foreach( _listOPCServer 中的var i”)

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

这实际上是错误。

我确定我做错了什么,有人能帮帮我吗?

3 个答案:

答案 0 :(得分:4)

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

 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);
            }

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

答案 1 :(得分:2)

VB.NET在处理不符合规范的数组类型方面更加精明。不要犹豫使用它,.NET可以让语言相互交互变得容易。

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

然而,0作为下限是C#在处理一维数组时所坚持的。它需要一个“向量”,一个不同的数组类型,它始终具有一个维度,其下限为0.在.NET运行时中进行了大量优化。您得到的内容不匹配,因此映射到一维维度的多维数组。不是您可以用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..
}

答案 2 :(得分:1)

虽然Hans在区分从零开始的数组和基于非零的数组之间的差异方面是正确的,但我仍然不明白为什么你会得到这个例外。

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

由于您正在遍历数组并提取string,编译器可能会尝试将对象强制转换为string[],而Hans指出该对象无效

您应该能够将_listOPCServer投射到Array并按原样使用foreach

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