Итерирование Systems.Collections.List в Fujitsu COBOL - PullRequest
4 голосов
/ 08 июня 2011

Как перебрать коллекцию?

Я использую пробную версию компилятора Fujitsu / Alchemy и получаю медленную и слабую поддержку от поставщика.

Я в основном хочупередать List из C # в COBOL, а затем позволить COBOL использовать его и, возможно, обновить.

В C # обычным способом перебора коллекции является использование конструкции "foreach".

Тем не менее, конструкция C # «foreach» является сокращением для следующего:

private static void test1()
{
    List<IDMSMapField> list1 = new List<IDMSMapField>();
    int listSize = list1.Count;
    // was just checking exact variablename and case here to copy into COBOL code.
    int itemNumber = 0;

    System.Collections.Generic.List<IDMSMapField>.Enumerator enumerator1 = list1.GetEnumerator();

    while (enumerator1.MoveNext())
    {
        Console.Write("Okay" + enumerator1.Current);
    }
}

Я могу написать это на языке COBOL, если вы можете помочь мне разобраться с объявлением этого класса:

System.Collections.Generic.List<IDMSMapField>.Enumerator

Структура "Enumerator" задокументирована на сайте MSDN Microsoft .

Это говорит о том, что "Enumerator" является структурой, а не классом!

Из того, что яВ руководстве «Создание COBOLfromDotnetFrameworkDox.pdf» можно указать, что структуры определены как классы в хранилище COBOL.

Пример из руководства:

Define specifiers for structure in REPOSITORY, and any struct members:
CLASS STRUCT-name AS "struct-namespace"
PROPERTY PROP-struct-member AS "external-property-name"
Handle structures like classes. E.g. object to store a struct instance:
01 struct-object OBJECT REFERENCE STRUCT-name.

Ниже я повторяю некоторые вариантыЯ пытался, что все не удалоськомпилировать из-за ошибки «невозможно решить».Если вы можете показать мне, как это правильно объявить, я думаю, что мы можем двигаться вперед.

1.

    REPOSITORY.
           CLASS  CLASS-LIST         AS "System.Collections.Generic.List<>"
           CLASS  STRUCT-Enumerator  AS "System.Collections.Generic.List<>.Enumerator"
           .

Ошибка во второй строке:

ошибкаJMN1795I-S: именованная ссылка 'System.Collections.Generic.List <>. Enumerator' не может быть разрешена.

  1. Точно такая же ошибка для этого:

        REPOSITORY.
               CLASS  CLASS-LIST         AS "System.Collections.Generic.List<>"
               CLASS  STRUCT-Enumerator  AS "System.Collections.Generic.List<T>.Enumerator"
               .
    

ошибка JMN1795I-S: именованная ссылка 'System.Collections.Generic.List.Enumerator' не может быть разрешена.

  1. Та же ошибка для этого:

    Хранилище.CLASS CLASS-LIST AS "System.Collections.Generic.List <>" CLASS STRUCT-Enumerator как "System.Collections.Generic.List.Enumerator".

ошибка JMN1795I-S: именованная ссылка 'System.Collections.Generic.List.Enumerator' не может быть разрешена.

Другой альтернативой является обработка ее как массива, но я также застрял на этом.

REPOSITORY.
    CLASS LIST-IDMSMapField    AS "System.Collections.Generic.List<>[]"
    CLASS CLASS-IDMSMapField   AS "Lightyear.ERCB.IDMSDC.IDMSMapField"
    CLASS CLASS-LIST-IDMSMapField EXPANDS LIST-IDMSMapField USING CLASS-IDMSMapField.

METHOD-ID. TW1DR4000-PF06 AS "TW1DR4000_PF06".
DATA DIVISION.
WORKING-STORAGE SECTION.

01 MapFieldItem USAGE OBJECT REFERENCE CLASS-IDMSMapField.

LINKAGE SECTION.

01 MapFieldList USAGE OBJECT REFERENCE CLASS-LIST-IDMSMapField.

PROCEDURE DIVISION...
...
SET MapFieldItem TO MapFieldList(1).

ошибка JMN2671I-S: ':' должно быть указано в модификаторе ссылки.':' предполагается.

Я думаю, что компилятор видит (1) как операцию подстроки.

Ответы [ 2 ]

3 голосов
/ 09 июня 2011

Это заняло некоторое время, но вот полный рабочий образец.Было несколько других приемов, чтобы получить свойства и переместить значения свойств, такие как Count, в переменную COBOL с соответствующим предложением USAGE.Ключевое слово «EXPANDS» (в хранилище) является еще одной ключевой частью решения.

В моей настоящей программе я получу список в разделе LINKAGE, и у меня будет список более сложных объектов ... но пример кода представляет собой более простой сценарий, который стоит отдельно иработает "как есть".

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MAIN AS "COBOLEnumerationSample.Main".
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SPECIAL-NAMES.
   REPOSITORY.
       CLASS List        AS "System.Collections.Generic.List<>"
       CLASS SysString   AS "System.String"
       CLASS SysBoolean  AS "System.Boolean" 
       CLASS ListString EXPANDS List USING SysString
       CLASS Enumerator  AS "System.Collections.Generic.List<>+Enumerator"
       CLASS StringEnumerator EXPANDS Enumerator USING SysString
       PROPERTY PROP-Count   AS "Count"      
       PROPERTY PROP-Current AS "Current"
       .       
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 myList              OBJECT REFERENCE ListString.
   01 myEnum              OBJECT REFERENCE StringEnumerator.   
   01 myBooleanEnumResult OBJECT REFERENCE SysBoolean. 
   01 myDotNetString      OBJECT REFERENCE SysString.  
   01 myLoopCounter       PIC 9(4)  value zero. 
   01 myCobolCount        PIC S9(9) COMP-5 VALUE ZERO.
   01 myCobolString       PIC X(30) value spaces. 
   01 YN-END-LOOP         PIC X     value "N". 
   01 WS-ACCEPT-INPUT     PIC X(80) value spaces. 

   PROCEDURE DIVISION.
   1000-START.
       INVOKE ListString "NEW" returning myList.
       INVOKE myList "Add" using "Apples"
       INVOKE myList "Add" using "Bananas"
       INVOKE myList "Add" using "Orange"


       SET myCobolCount to PROP-Count of myList 
       DISPLAY "Size of MyList = " myCobolCount

       INVOKE myList "GetEnumerator" returning myEnum.


       PERFORM UNTIL YN-END-LOOP = "Y" 
             INVOKE myEnum "MoveNext" returning myBooleanEnumResult  
  * How to test for Boolean, True = B'1' and False = B'0' 
             IF myBooleanEnumResult = B'0' 
                MOVE "Y" TO YN-END-LOOP 
             ELSE       
                SET myDotNetString TO PROP-Current of myEnum 
                ADD 1 TO myLoopCounter
                SET myCobolString to myDotNetString 
                DISPLAY myLoopCounter " " myCobolString 
             END-IF    

       END-PERFORM 

       DISPLAY "END OF PROGRAM - PRESS ENTER TO END" 
       ACCEPT WS-ACCEPT-INPUT
       .

   END PROGRAM MAIN.
0 голосов
/ 11 июня 2011

Используя реализацию .NET для Micro Focus, код может использовать расширение «выполнить изменение», чтобы просмотреть список.

Итак, настроенная версия:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MAIN AS "COBOLEnumerationSample.Main".
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SPECIAL-NAMES.
   REPOSITORY.
       CLASS List        AS "System.Collections.Generic.List"
       CLASS SysString   AS "System.String"
       CLASS SysBoolean  AS "System.Boolean"
       CLASS ListString EXPANDS List USING SysString
       PROPERTY PROP-Count   AS "Count"
       PROPERTY PROP-Current AS "Current"
       .
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 myList              OBJECT REFERENCE ListString.
   01 myLoopCounter       PIC 9(4)  value zero.
   01 myCobolCount        PIC S9(9) COMP-5 VALUE ZERO.
   01 myCobolString       PIC X(30) value spaces.
   01 WS-ACCEPT-INPUT     PIC X(80) value spaces.

   PROCEDURE DIVISION.
   1000-START.
       INVOKE ListString "NEW" returning myList.
       INVOKE myList "Add" using "Apples"
       INVOKE myList "Add" using "Bananas"
       INVOKE myList "Add" using "Orange"

       SET myCobolCount to PROP-Count of myList
       DISPLAY "Size of MyList = " myCobolCount

       move 0 to myLoopCounter
       PERFORM varying myCobolString through myList
           DISPLAY myLoopCounter " " myCobolString
           ADD 1 to myLoopCounter
       END-PERFORM

       DISPLAY "END OF PROGRAM - PRESS ENTER TO END"
       ACCEPT WS-ACCEPT-INPUT
       .

   END PROGRAM MAIN.

Далее, вместо использования синтаксиса и расширений репозитория, вы можете использовать встроенное объявление, например:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MAIN AS "COBOLEnumerationSample.Main".
   WORKING-STORAGE SECTION.
   01 myList         type "System.Collections.Generic.List"[string].
   01 myLoopCounter   PIC 9(4)  value zero.
   01 myCobolCount    PIC S9(9) COMP-5 VALUE ZERO.
   01 myCobolString   PIC X(30) value spaces.
   01 WS-ACCEPT-INPUT PIC X(80) value spaces.

   PROCEDURE DIVISION.
   1000-START.
       INVOKE type "System.Collections.Generic.List"[string]::"NEW"
             returning myList
       INVOKE myList "Add" using "Apples"
       INVOKE myList "Add" using "Bananas"
       INVOKE myList "Add" using "Orange"


       SET myCobolCount TO myList::"Count"
       DISPLAY "Size of MyList = " myCobolCount

       MOVE 0 TO myLoopCounter
       PERFORM varying myCobolString through myList
           DISPLAY myLoopCounter " " myCobolString
           ADD 1 TO myLoopCounter
       END-PERFORM

       DISPLAY "END OF PROGRAM - PRESS ENTER TO END"
       ACCEPT WS-ACCEPT-INPUT
       .

   END PROGRAM MAIN.

В любом случае, мне просто нравится, что мы можем делать это в COBOL, независимо от того, какой продукт используется .. Наслаждайтесь ...

...