如何循环收藏?
我正在使用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
“枚举器”结构为documented on Microsoft's MSDN site。
它告诉“Enumerator”是一个Struct,而不是一个Class!
根据我在手册“CreatingCOBOLfromDotnetFrameworkDox.pdf”中的说法,结构被定义为COBOL REPOSITORY中的类。
手册中的示例:
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&lt;&gt; .Enumerator'。
完全相同的错误:
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'。
同样的错误:
存储库。 CLASS CLASS-LIST AS“System.Collections.Generic.List&lt;&gt;” 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)视为子字符串操作。
答案 0 :(得分:3)
花了一段时间,但这是一个完整的工作样本。 有几个其他的技巧到达物业, 并使用适当的USAGE子句将Count等属性值移动到COBOL变量。 “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.
答案 1 :(得分:0)
使用Micro Focus的.NET实现,代码可以使用“执行不同的”扩展来遍历列表。
所以调整后的版本是:
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中做到这一点,无论使用哪种产品..享受......