C #: объект в массив строк. Ошибка от [*] до [] (знание как VB.NET, так и C # помогает) - PullRequest
1 голос
/ 30 марта 2012

Мне было поручено преобразовать проект VB.NET в C #, и я застрял.Я использую класс RsiOPCAuto, но я не думаю, что мне придется вдаваться в подробности, чтобы объяснить, как он работает.Давайте продолжим с моей проблемой.

Итак, в основном, я делаю захват объекта из моего класса, используя этот код:

public partial class FrmPartialMain : Form
{
    RsiOPCAuto.OPCServer oOpcServer;
    public FrmPartialMain()
    {
        InitializeComponent();
        object RsiOPCAuto;
        object oOPCList;

        oOpcServer = new RsiOPCAuto.OPCServer();
        oOPCList = oOpcServer.GetOPCServers();

Пока все хорошо.Добавив часы, я вижу, что теперь у oOPCList есть значение {string [1..4]}.

Теперь я хочу поместить эти четыре строки в поле со списком.Я делаю это с помощью простого цикла for:

for (int i = 0; i <= oOPCList.Length; i++)
{
    cboServer.Items.Add(oOPCList[i]);
}

Редактировать: поцарапать это, изменил это на гораздо более хороший цикл foreach.

Несмотря на то, что этот объект теперь работает как строковый массив, oOPCList.Length и (oOPCList [i]) получают ошибки:

.Length: Ошибка 1 «объект» не содержит определениядля 'Length' и метода расширения 'Length', принимающего первый аргумент типа 'object', не найдено (вы пропустили директиву using или ссылку на сборку?)

oOPCList [i]: Ошибка 2 Невозможно применить индексирование с [] к выражению типа 'объект'

Могу поспорить, что это самая простая вещь, но я просто не могу ее увидеть, помощь очень ценится, и если есть что-то ещевам нужно знать обязательно спросить: -)

PS.Возможно, стоит упомянуть, что я пробовал несколько разных способов преобразования объекта в строковый массив, но постоянно получаю сообщение об ошибке, сообщающее, что я не могу преобразовать system.string [*] в system.string [].

Это код VB.NET, который я конвертирую:

Friend Class frmPartialMain
    Inherits System.Windows.Forms.Form
        Dim oOpcServer As RsiOPCAuto.OPCServer
        Private Sub frmPartialMain_Load(ByVal eventSender As System.Object, ByVal eventArgs As  System.EventArgs) Handles MyBase.Load
            Dim RsiOPCAuto As Object
            Dim oOPCList() As Object
            Dim i As Integer

            oOpcServer = New RsiOPCAuto.OPCServer
            oOPCList = oOpcServer.GetOPCServers
            For i = LBound(oOPCList) To UBound(oOPCList)
                cboServer.Items.Add(oOPCList(i))
            Next i

Ответы [ 5 ]

3 голосов
/ 30 марта 2012

Вам необходимо сначала преобразовать возвращаемое значение GetOPCServers в object, затем в Array, поскольку этот метод возвращает тип dynamic. Вы не можете напрямую привести к string[], потому что массивы со строгим типом, которые не основаны на 0, не поддерживаются C #. После приведения вам нужно вызвать Cast<string>, чтобы получить перечислимый тип со строгим типом, который вы можете повторить:

IEnumerable<string> oOPCList;

oOpcServer = new RsiOPCAuto.OPCServer();
oOPCList = ((Array)(object)oOpcServer.GetOPCServers()).Cast<string>();

Кроме того, вам лучше использовать цикл foreach, потому что он намного более читабелен:

foreach(var item in oOPCList)
    cboServer.Items.Add(item);

Требуется странное приведение сначала к object, затем к Array, а затем к IEnumerable<string> через Cast<string> из-за следующего:

GetOPCServers возвращает тип dynamic. Попытка получить доступ к этому динамическому экземпляру любым способом - даже через вызов GetType вызывает InvalidCastException. Поэтому сначала его необходимо привести к object, чтобы он больше не являлся динамическим типом. После этого мы можем привести его к Array, единственному поддерживаемому в C # способу работы с ненулевыми массивами. Но Array не является строго типизированным, поэтому мы добавляем вызов к Cast<string>, чтобы получить перечислимый тип со строгим типом.

1 голос
/ 30 марта 2012

Во-первых, вы можете получить доступ только к членам объекта, имеющего ссылочный тип.Поэтому, если вы поместите строковый массив в поле или переменную типа object, вы сможете получить доступ только к тем элементам, которые определены в самом объекте (например, ToString) .

string[*] означает, что массив - это массив, который проиндексирован с чем-то отличным от нуля, что обычно означает, что он проиндексирован, начиная с 1. (Я не могу вспомнить, как конвертировать их, но я посмотрю его).

Редактировать: см. этот ответ о том, как работать с ненулевым массивом в C #.

Хотя возможно создание и работа с таким массивом, его использованиев C # является исключительным, поэтому вам придется обращаться к нему через переменную типа Array, так как string[*] недопустим в C #.

† Тем не менее, можно было бы получить к ним косвенный доступ с помощью Reflection.

0 голосов
/ 30 марта 2012

Вы получаете эти ошибки, потому что oOPCList является объектом.Он не содержит ни длинных, ни [] индексаторов.Использовать тип, возвращаемый oOpcServer.GetOPCServers ()

0 голосов
/ 30 марта 2012

Попробуйте это:

foreach(var opc in oOpcServer.GetOPCServers().ToList()) {
    cboServer.Items.Add(oOPCList[i]);
}
0 голосов
/ 30 марта 2012

Вы объявили oOPCList как объект, который не имеет свойства длины и, следовательно, не может быть повторен.Что возвращает oOpcServer.GetOPCServers ()?Это массив?

Объявите oOPCList как один и тот же тип, и вы можете использовать цикл for или foreach

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...