Unable To Cast object type 'System.String[*]' to type 'System.String[]'

痴心易碎 提交于 2019-12-02 01:13:21

Ok i found a way to work this out and it's only a mod of your advices

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

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

I only added (object) in the declaration and works fine, now i can show the list of servers just the way i wanted it

or also do this

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

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

Again, thanks a lot for your help and time!

VB.NET is a lot more astute at dealing with non-conforming array types. Don't hesitate to use it, .NET make it easy to have languages inter-operate with each other.

At issue is that OPC is a COM based standard. The server you are using is returning a SAFEARRAY with a non-conforming lower bound, the first index is 1. Not 0. Not that unusual in COM, choosing between 0 and 1 as the first array index is like the endian problem or arguing whether a tomato is a fruit or a vegetable (It is a fruit. And little-endian is the right kind of vegetable).

However, 0 as the lower bound is what C# insists on when dealing with one-dimensional arrays. It wants a "vector", a distinct array type that always has one dimension with a lower bound of 0. Heavily optimized in the .NET runtime. What you get back doesn't match so is mapped to a multi-dimensional array with one dimension. Not an array type you can express in the C# language.

You can hack it in C#, but you'll have to use the Array type explicitly. Something like this, spelled out for clarity:

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..
}
D Stanley

While Hans is correct in distinguishing the difference between a zero-based array and a non-zero-based array, I still don't see why you're getting that exception.

My guess is that you're declaring _OPCServer as dynamic, which defers type-binding until run-time. Thus _listOPCServer is dynamic as well.

Since you're iterating over the array and extracting strings, the compiler may be trying to cast the object to a string[] which as Hans points out is invalid.

You should be able to cast _listOPCServer to an Array and use the foreach just as you are:

Array _listOPCServer = (Array)(_OPCServer.GetOPCServers());
foreach(var i in _listOPCServer)
{
    // etc.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!