COBOL / C# /Java Comparison

COBOL / C# /Java Comparison

COBOL / C# /Java Comparison COBOL C# Java Program Structure class-id HelloWorld as "Hello.Helloworld". method-id main static. local-storage section. 01 helloString string value "COBOL". procedure division using by value args as string occurs any. if length of args > 0 set helloString to args(1) end-if display "Hello & helloString ! " end method. end class. namespace Hello { public class HelloWorld { public static void Main(string[] args) { string helloString = "C#"; if (args.Length > 1) { helloString = args[0]; } System.Console.WriteLine("Hello, " + helloString ) ; } } } package Hello; public class HelloWorld { public static void main(String[] args) { String helloString = "Java"; if (args.length > 1) { helloString = args[0]; } System.out.println("Hello, " + helloString ) ; } } Comments * in column 7 when comments out rest of line (COBOL fixed format) *> rest of the line comment, may follow COBOL statements *>> XML comments // Rest of line /* Multiple lines */ /// XML comments on single line /** XML comments on multiple lines */ // Rest of the line /* Multiple line */ /** Java doc.

Type /** Eclipse will autocomplete */ Data Types Value Types condition-value binary-char unsigned, binary-char character binary-short (unsigned) binary-long (unsigned) binary-double (unsigned) float-short, float-long decimal DateTime (not a built-in COBOL type) Reference types object string Initializing 01 isTrue condition-value value true. 01 hex binary-char unsigned value h"2a". *> Hex 01 octal binary-char unsigned value o"52". *> Octal 01 person object value null. 01 aName string value "Dwight". 01 grade character value "B". 01 today type DateTime value type DateTime::Parse("12/31/2007 12:15:00").

01 amount decimal value 35.99.

01 gpa float-short value 2.9. 01 pi float-long value 3.14159265. 01 lTotal binary-double value 123456. 01 sTotal binary-short value 123. 01 usTotal binary-short unsigned value 123. 01 uiTotal binary-long value 123. 01 ulTotal binary-long unsigned value 123. Type Information 01 x binary-long. display x::GetType *> Prints System.Int32 display type of binary-long *> Prints System.Int32 display x::GetType::Name *> Prints Int32 Type Conversion 01 d float-short value 3.5. *> automatic conversion set i to d as binary-long *> set to 3 (truncates decimal) COBOL types not supported in C# or Java *> Only a few examples here 01 displayNumber pic 9(9).99.

01 computeNumber pic 9(9)V99. 01 alphaNumberic pic a(23). 01 binaryStorage pic x(12). *> Also groups and redefines - a few examples 01 arecord.

03 aSubRecord pic x(10). Value Types bool byte, sbyte char short, ushort int, uint long, ulong float, double decimal DateTime (not a built-in C# type) Reference Types object string Initializing bool isTrue = true; byte hex = 0x2A; // hex object person = null; string aName = "Dwight"; char grade = 'B'; DateTime today = DateTime.Parse("12/31/2007 12:15:00"); decimal amount = 35.99m; float gpa = 2.9f; double pi = 3.14159265; long lTotal = 123456L; short sTotal = 123; ushort usTotal = 123; uint uiTotal = 123; ulong ulTotal = 123; Type Information int x; Console.WriteLine(x.GetType()); // Prints System.Int32 Console.WriteLine(typeof(int)); // Prints System.Int32 Console.WriteLine(x.GetType().Name); // prints Int32 Type Conversion float d = 3.5f; int i = (int)d; // set to 3 (truncates decimal) Value Types boolean byte char short int long float, double Date (not a built-in Java) Reference Types java.lang.Object java.lang.String Initializing boolean correct = true; byte b = 0x2A; // hex Object person = null; String name = "Dwight"; char grade = 'B'; Date today = Date.parse("12/31/2007 12:15:00"); float gpa = 2.9f; double pi = 3.14159265; long lTotal = 123456L; short sTotal = 123; int iTotal = 123; Type Information Use reflection Type Conversion float d = 3.5f; int i = (int)d; // set to 3 (truncates decimal)

03 aUnion pic 9(10) redefines aSubrecord. Constants 78 MAX_STUDENTS value 25. *> optionally public, binary-long... *> INITIALIZE ONLY - instance or static, may be initialized in constructor 01 MIN_DIAMETER float-short value 4.93 initialize only. const int MAX_STUDENTS = 25; // Can set to a const or var; may be initialised in a constructor readonly float MIN_DIAMETER = 4.93f; final int MAX_STUDENTS = 25; Enumeration enum-id Action. 78 #Start. *> Start is a reserved word 78 #Stop. 78 #Rewind. 78 #Forward. end enum. enum-id Status. 78 Flunk value 50. 78 Pass value 70. 78 Excel value 90. end enum.

program-id main. display type Status::Pass as binary-long *> prints 70 display type Status::Pass *> prints Pass end program. enum Action {Start, Stop, Rewind, Forward}; enum Status {Flunk = 50, Pass = 70, Excel = 90}; Action a = Action.Stop; if (a != Action.Start) Console.WriteLine(a + " is ( int) a / Prints "Stop is 1" Console.WriteLine((int) Status.Pass); // Prints 70 Console.WriteLine(Status.Pass); // Prints Pass enum Action {Start, Stop, Rewind, Forward}; public enum Status { Flunk (50), Pass (70), Excel (90); private final int val; Status(int valIn) { this.val = valIn; } } Action a = Action.Stop; if (a != Action.Start) System.out.println(a); // Prints "Stop" System.out.println(Status.Pass.val); // Prints 70 System.out.println(Status.Pass / prints Pass Operators Comparison = Arithmetic / function mod *>no direct COBOL equivalent to integer division ** Assignment move, set, compute Bitwise b-and, b-or, b-xor, b-not, b-left, b-right Logical and, or, not String Concatenation & Comparison ! = Arithmetic / % (mod) / (integer division if both operands are ints) Math.Pow(x, y) Assignment - - Bitwise > Logical !

//Note: && and || perform short-circuit logical evaluations String Concatenation + Comparison ! = Arithmetic / % (mod) / (integer division if both operands are ints) Assignment ^ = - - Bitwise > Logical ! String Concatenation + Choices *>COBOL has no exact equivalent syntax to x ? y : z if age < 20 move "What's up?" to greeting else move "Hello" to greeting end-if if x not = 100 and y < 5 multiply 5 by x multiply 2 by y end-if *> evaluate is preferred in COBOL rather than if/else if/else evaluate x when > 5 multiply y by x when 5 add y to x when < 10 subtract y from x when other divide y into x end-evaluate evaluate color *> can be any type when "turquoise" when "red" add 1 to r when "turquoise" add 1 to b when "green" greeting = age < 20 ? "What's up?" : "Hello"; // Good practice is that all consequents are enclosed in {} // or are on the same line as if.

if (age < 20) greeting = "What's up?"; else { greeting = "Hello"; } // Multiple statements must be enclosed in {} if (x != 100 && y < 5) { x *= 5; y *= 2; } if (x > 5) { x *= y; } else if (x == 5) { x += y; } else if (x < 10) { x -= y; } else { x /= y; } greeting = age < 20 ? "What's up?" : "Hello"; // Good practice is that all consequents are enclosed in {} // although optional if 1 line if (age < 20) greeting = "What's up?"; else greeting = "Hello"; // Multiple statements must be enclosed in {} if (x != 100 && y < 5) { x *= 5; y *= 2; } if (x > 5) { x *= y; } else if (x == 5) { x += y; } else if (x < 10) { x -= y; } else { x /= y; }

add 1 to g when other add 1 to other-color end-evaluate // Every case must end with break or goto case switch (color) // Must be integer or string { case "turquoise": case "red": r++; break; case "turquoise": b++; break; case "green": g++; break; default: other++; break; // break necessary on default } switch (color) { case "turquoise": case "red": r++; break; case "turquoise": b++; break; case "green": g++; break; default: other++; break; } Loops Pre-test loops: perform until c >= 10 add 1 to c end-perform perform varying c from 2 by 2 until c > 10 display c end-perform Post-test loops: perform with test after until c >= 10 add 1 to c end-perform Array or collection looping 01 names string occurs any.

01 s string.

set content of names to ("Rod", "Jane", "Freddy") perform varying s through names display s end-perform Breaking out of loops: 01 i binary-long value 0. perform until exit if i = 5 exit perform end-if add 1 to i end-perform Continue to next iteration: 01 i binary-long value 0 perform varying i from 0 by 1 until i >= 5 if i < 4 exit perform cycle end-if display i *> Only prints 4 end-perform Pre-test Loops: // no "until" keyword while (c < 10) { c++; } for (c = 2; c 5 is the size of the array 01 names string occurs 5.

*> Can also do: 01 names string occurs any. set size of names to 5 set names(1) to "Rod" *> first element indexed as 1 set names(6) to "Jane" *> throws IndexOutOfRangeException *> COBOL cannot resize an array - use copy 01 names2 string occurs 7.

invoke type Array::Copy(names, names2, names::Length) *> or else: invoke names::CopyTo(names2, 0) *> or else: invoke type Array::Resize(names, 7) 01 twoD float-short occurs any, any. set size of twoD to rows, cols 01 jagged binary-long occurs any, occurs any. set size of jagged to 3 set size of jagged(1) to 5 set jagged(1, 5) to 5 int[] nums = {1, 2, 3}; for (int i = 0; i < nums.Length; i++) { Console.WriteLine(nums[i]); } // 5 is the size of the array string[] names = new string[5]; names[0] = "Rod"; names[5] = "Jane / Throws System.IndexOutOfRangeException // C# can't dynamically resize an array.

Just copy into new array.

string[] names2 = new string[7]; // or names.CopyTo(names2, 0); Array.Copy(names, names2, names.Length); float[,] twoD = new float[rows, cols]; twoD[2,0] = 4.5f; int[][] jagged = new int[3][] { new int[5], new int[2], new int[3] }; jagged[0][4] = 5; int[] nums = {1, 2, 3}; for (int i = 0; i < nums.length; i++) { System.out.println(nums[i]); } // 5 is the size of the array String[] names = new String[5]; names[0] = "Rod"; names[5] = "Jane / Throws java.lang.ArrayIndexOutOfBoundsExcept ion // Copy an array into a new array. String[] names2 = new String[7]; System.arraycopy(names, 0, names2, 0, names.length); float[][] twoD; twoD = new float[rows][cols]; // In Java this is just a multi- dimensional array int[][] jagged = {{1, 2, 3}, {1, 2, 3, 4, 5}, {1, 2}};

System.out.println("jagged[0][2] = " + jagged[0][2 / / prints 3 Functions method-id TestFunc. procedure division using value x as binary- long, reference y as binary-long, output z as binary- long. add 1 to x, y move 5 to z end method. 01 a binary-long value 1. 01 b binary-long value 1. 01 c binary-long. *> c doesn't need initializing invoke self::TestFunc(value a, reference b, output c) *> Or invoke self::TestFunc(a, b, c) display a space b space c *> sum is an intrinsic function in COBOL 01 total binary-long.

set total to function sum(4, 3, 2, 1) *> returns 10 *> To create a non intrinsic variable argument list function: method-id MySum.

local-storage section. 01 i binary-long. procedure division using params nums as binary-long occurs any returning mysum as binary- long. perform varying i through nums add i to mysum end-perform end method. *> then to call it: method-id main. local-storage section. 01 i binary-long. procedure division. set i to self::MySum(1, 2, 3, 4) display i end method. *> COBOL doesn't support optional arguments/parameters.

*> Just create two different versions of the same function. method-id SayHello. procedure division using value nam as string, prefix as string. display "Greetings, " prefix space nam end method. method-id SayHello. procedure division using value nam as string. invoke self::SayHello(nam "") end method. // Pass by value (in, default), reference (in/out), // and reference (out) void TestFunc(int x, ref int y, out int z) { x++; y++; z = 5; } int a = 1, b = 1, c; // c doesn't need initializing TestFunc(a, ref b, out c); Console.WriteLine("{0} {1} {2}", a, b, c / 1 2 5 // Accept variable number of arguments int Sum(params int[] nums) { int sum = 0; foreach (int i in nums) { sum += i; } return sum; } int total = Sum(4, 3, 2, 1); // returns 10 /* C# doesn't support optional arguments/parameters.

Just create two different versions of the same function. */ void SayHello(string name, string prefix) { Console.WriteLine("Greetings, " + prefix + name); } void SayHello(string name) { SayHello(name ) ; } // In Java there is no REF or OUT option on method parameters. // Everything is passed by value. However for a parameter of reference // type (i.e. not a primitive) it is the reference itself which is // passed by value, hence it appears to be pass-by-reference. void TestFunc(int x, int y, int z) { x++; y++; z = 5; } int a = 1, b = 1, c = 2; TestFunc(a, b, c); System.out.println(a + b + c / 1 1 2 // Accept variable number of arguments int Sum(int[] nums) { int sum = 0; for (int i = 0; i < nums.length; i++) { sum += i; } return sum; } int[] nums = {1, 2, 3, 4}; int total = Sum(nums / returns 10 // Java supports optional parameters void SayHello(String...

strings) { for (String s : strings) System.out.println("Greetings, " + s); } SayHello("Strangelove", "Dr"); SayHello("Madonna"); Strings Escape sequences x"0a" *> line-feed x"09" *> tab > backslash > quote String concatenation 01 school string value "Harding" & x"09". set school to school & "University" *> school is "Harding (tab) University" Chars 01 letter character. 01 word character occurs any. set letter to school::Chars(0) *> letter is H set letter to type Convert::ToChar(65) *> letter is A set letter to 65 as character *> same thing set word to school::ToCharArray *> word holds Harding String literal 01 msg string value "File is c:\temp\x.dat".

Escape sequences \r // carriage-return \n // line-feed \t // tab / backslash / quote String concatenation string school = "Harding\t"; school = school + "University"; // school is "Harding (tab) University" Chars char letter = school[0]; // letter is H letter = Convert.ToChar(65); // letter is A letter = (char)65; // same thing char[] word = school.ToCharArray / / word holds Harding String literal string msg = @"File is c:\temp\x.dat"; // same as string msg = "File is c:\\temp\\x.dat"; Escape sequences \r // carriage-return \n // line-feed \t // tab / backslash / quote String concatenation String school = "Harding\t"; school = school + "University"; // school is "Harding (tab) University" Chars char letter = school.charAt(0); // letter is H letter = (char)65; // letter is A char[] word = school.toCharArray(); // word holds Harding String literal String msg = "File is c:\\temp\\x.dat";

String comparison 01 mascot string value "Beatles". if mascot = "Beatles" *> true if mascot::Equals("Beatles") *> true if mascot::ToUpper::Equals("BEATLES") *> true if mascot::CompareTo("Beatles") = 0 *> true Substring set s to mascot::Substring(1, 3) *> s is "eat" Replacement set s to mascot::Replace("Beatl", "Monke") *> s is "Monkees" Split 01 names string value "John,Paul,George,Ringo". 01 parts string occurs any. set parts to names::Split(",") Date to string 01 dt type DateTime value new DateTime(1973, 10, 12).

01 s string. set s to dt::ToString("MMM dd, yyyy") *> Oct 12, 1973 int to string 01 x binary-long value 2.

01 y string. set y to type x::ToString *> x is "2" string to int 01 x binary-long. set x to type Convert::ToInt32("-5 > x is -5 Mutable string 01 buffer type System.Text.StringBuilder value new System.Text.StringBuilder("two "). invoke buffer::Append("three") invoke buffer::Insert(0, "one ") invoke buffer::Replace("two", "TWO") display buffer *> Prints "one TWO three" String comparison string mascot = "Beatles"; if (mascot == "Beatles") // true if (mascot.Equals("Beatles")) // true if (mascot.ToUpper().Equals("BEATLES")) // true if (mascot.CompareTo("Beatles = 0) // true Substring s = mascot.Substring(1, 3 / s is "eat" Replacement s = mascot.Replace("Beatl", "Monke / / s is "Monkees" Split string names = "John,Paul,George,Ringo"; // One name in each slot string[] parts = names.Split(",".ToCharArray()); Date to string DateTime dt = new DateTime(1973, 10, 12); string s = dt.ToString("MMM dd, yyyy"); // Oct 12, 1973 int to string int x = 2; string y = x.ToString / y is "2" string to int int x = Convert.ToInt32("-5 / x is -5 Mutable string System.Text.StringBuilder buffer = new System.Text.StringBuilder("two "); buffer.Append("three "); buffer.Insert(0, "one "); buffer.Replace("two", "TWO"); Console.WriteLine(buffer / Prints "one TWO three" String comparison String mascot = "Beatles"; if (mascot == "Beatles") // true if (mascot.contentEquals("Beatles")) // true if (mascot.toUpperCase().contentEquals(" BEATLES / true if (mascot.compareTo("Beatles = 0) // true Substring NB this is different behaviour to C#, startIndex endIndex String s = mascot.substring(1, 3); // s is "ea" Replacement s = mascot.replace("Beatl", "Monke"); // s is "Monkees" Split String names = "John,Paul,George,Ringo"; // One name in each slot String[] parts = names.split ) ; Date to string java.util.Date dt = new java.util.Date(); java.text.SimpleDateFormat dateformatMMDDYYYY = new java.text.SimpleDateFormat("MMddyyyy" ); StringBuilder nowMMDDYYYY = new StringBuilder(dateformatMMDDYYYY.form at(dt)); s = "Today is " + nowMMDDYYYY; int to string int x = 2; String y = Integer.toString(x); // y is "2" String to int String minusFive = "-5"; int z = new Double(minusFive).intValue / / x is -5 Mutable string java.lang.StringBuilder buffer = new java.lang.StringBuilder("two "); buffer.append("three "); buffer.insert(0, "one "); buffer.replace(0, 2, "TWO / / start, end, string - different to C# System.out.println(buffer); // Prints "one TWO three" Exception Handling *> Throw an exception 01 excep type Exception value new Exception("Something is really wrong.").

raise excep *> Catch an exception try set y to 0 compute x = 10 / y catch excep *> Argument is optional, no "When" keyword display excep::Message finally invoke type Microsoft.VisualBasic.Interaction::Beep end-try // Throw an exception Exception up = new Exception("Something is really wrong."); throw up; // Catch an exception try { y = 0; x = 10 / y; } catch (Exception ex) // Argument is optional, no "When" keyword { Console.WriteLine(ex.Message); } finally { Microsoft.VisualBasic.Interaction.Beep() ; } import java.lang.*; // Throw an exception Exception up = new Exception("Something is really wrong."); throw new EmptyStackException(); // Catch an exception try { int y = 0; int x = 10 / y; } catch (ArithmeticException ex) // Argument optional, no "When" keyword { System.out.println(ex.getMessage()); } finally { System.out.println("\007"); } Namespaces *> At the file level $set ilnamespace "Harding.Compsci.Graphics" *> The directive can also be set as a project *> level to apply the name space to all classes in the project.

namespace Harding.Compsci.Graphics { ... } // or namespace Harding { namespace Compsci // Packages are used to organize files or public types to avoid // type conflicts. // Package constructs can be mapped to a file system. package Harding.Compsci.Graphics ... // package cannot be nested

{ namespace Graphics { ... } } } using Harding.Compsci.Graphics; Classes / Interfaces Accessibility keywords public private internal protected protected internal static redefine Inheritance class-id FootballGame inherits type Competition. ... end class. Interface definition interface-id IAlarmClock.

... end interface. Extending an interface interface-id IAlarmClock extends type IClock. ... end interface. Interface implementation class-id WristWatch implements type IAlarmClock, type ITimer. ... end class. Accessibility keywords public private internal protected protected internal static new Inheritance class FootballGame : Competition { ... } Interface definition interface IAlarmClock { ... } Extending an interface interface IAlarmClock : IClock { ... } Interface implementation class WristWatch : IAlarmClock, ITimer { ... } Accessibility keywords public private protected static Inheritance class FootballGame extends Competition { ...

} Interface definition interface IAlarmClock { ... } Extending an interface interface IAlarmClock extends IClock { ... } Interface implementation class WristWatch implements IAlarmClock, ITimer { ... } Constructors / Destructors class-id SuperHero. working-storage section. 01 _powerLevel binary-long. method-id new.

procedure division. set _powerLevel to 0 end method. method-id new. procedure division using value powerLevel as binary-long. set _powerLevel to powerLevel end method. method-id Finalize override protected. *> Destructor code to free unmanaged resources. end method. end class. class SuperHero { private int _powerLevel; public SuperHero() { _powerLevel = 0; } public SuperHero(int powerLevel) { this._powerLevel= powerLevel; } ~SuperHero() { // Destructor code to free unmanaged resources. // Implicitly creates a Finalize method } } public class SuperHero { private int _powerLevel; public void SuperHero() { _powerLevel = 0; } public void SuperHero(int powerLevel) { this._powerLevel= powerLevel; } // Every class inherits the finalize() method from // java.lang.Object.

The method is called by the garbage // collector when it determines no more references to // the object exist. It should be overridden to clean-up // non-Java resources eg closing a file.

protected void finalize() { } } Using Objects 01 hero type SuperHero value new SuperHero. 01 hero2 type SuperHero. 01 obj object. 01 reader type StreamReader. 01 myLine string. set hero::Name to SpamMan set hero::PowerLevel to 3 invoke hero::Defend("Laura Jones") invoke type SuperHero::Rest *> Calling static method set hero2 to hero *> Both reference the same object set hero2::Name to "WormWoman" display hero::Name *> Prints WormWoman set hero to null *> Free the object SuperHero hero = new SuperHero(); hero.Name = "SpamMan"; hero.PowerLevel = 3; hero.Defend("Laura Jones"); SuperHero.Rest / Calling static method SuperHero hero2 = hero; // Both reference the same object hero2.Name = "WormWoman"; Console.WriteLine(hero.Name); // Prints WormWoman hero = null / Free the object SuperHero hero = new SuperHero(); hero.Name = "SpamMan"; hero.PowerLevel = 3; hero.Defend("Laura Jones"); SuperHero.Rest / Calling static method SuperHero hero2 = hero; // Both reference the same object hero2.Name = "WormWoman"; System.out.println(hero.Name); // Prints WormWoman hero = null / Free the object

if hero = null set hero to new SuperHero end-if set obj to new SuperHero if obj is instance of type SuperHero display "Is a SuperHero object." end-if *> No 'using' construct in COBOL try set reader to type File::OpenText("test.txt") perform until exit set myLine to reader::ReadLine if myLine = null exit perform end-if end-perform finally if reader not = null invoke reader::Dispose end-if end-try if (hero == null) hero = new SuperHero(); Object obj = new SuperHero(); if (obj is SuperHero) { Console.WriteLine("Is a SuperHero object."); } // Mark object for quick disposal using (StreamReader reader = File.OpenText("test.txt")) { string line; while ((line = reader.ReadLine ! = null) { Console.WriteLine(line); } } if (hero == null) hero = new SuperHero(); Object obj = new SuperHero(); if (obj instanceof SuperHero) { System.out.println("Is a SuperHero object."); } // Mark object for quick disposal FileInputStream fstream = new FileInputStream("test.txt"); DataInputStream in = new DataInputStream(fstream); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line; while ((line = br.readLine ! = null) { System.out.println(line); } Structures (Value Types) *> COBOL uses valuetype-id to define a value type valuetype-id StudentRecord.

01 #name string public. 01 gpa float-short public. method-id new.

procedure division using value nam as string, gpa as float-short. set #name to nam set self::gpa to gpa end method. end valuetype. class-id a. method-id main static. local-storage section. 01 stu type StudentRecord value new StudentRecord("Bob", 3.5). 01 stu2 type StudentRecord. procedure division. set stu2 to stu set stu2::name to "Sue" display stu::name *> Prints Bob display stu2::name *> Prints Sue end method. end class. // C# uses struct to define a value type struct StudentRecord { public string name; public float gpa; public StudentRecord(string name, float gpa) { this.name = name; this.gpa = gpa; } } StudentRecord stu = new StudentRecord("Bob", 3.5f); StudentRecord stu2 = stu; stu2.name = "Sue"; Console.WriteLine(stu.name); // Prints Bob Console.WriteLine(stu2.name); // Prints Sue //Java doesn't have struct.

You may design a final class // or a simple class to replace struct class StudentRecord { public String name; public float gpa; public StudentRecord(String name, float gpa) { this.name = name; this.gpa = gpa; } } StudentRecord stu = new StudentRecord("Bob", 3.5f); StudentRecord stu2 = stu; stu2.name = "Sue"; System.out.println(stu.name); // Prints Bob System.out.println(stu2.name); // Prints Sue Properties class-id MyClass. working-storage section. 01 _size binary-long private. *> COBOL also allows you to expose fields as properties 01 _length binary-long property as "Length".

01 _width binary-long property as "Width" no get. 01 _breadth binary-long property as "Breadth" no set. method-id get property #Size. procedure division returning ret as binary- long. set ret to _size end method. method-id set property #Size. procedure division using value val as binary-long. if val < 0 set _size to 0 else set _size to val end-if end method. end class. class-id a. method-id main. local-storage section. 01 foo type MyClass value new MyClass. procedure division. add 1 to foo::Size display foo::Size end method.

end class. private int _size; private int _length; private int _width; private int _breadth; public int Size { get { return _size; } set { if (value < 0) { _size = 0; } else { _size = value; } } } public int Length { get { return _length; } set { _length = value; } } public int Width { set { _width = value; } } private int _size = 0; private int _length = 0; private int _width = 0; private int _breadth = 0; public int getSize() { return _size; } public void setSize(int value) { if (value < 0) { _size = 0; } else { _size = value; } } public int getLength() { return _length; } public void setLength(int value) { _size = value; } public void setWidth(int value) { _width = value; } public int getBreadth() { return _breadth; } foo.Size++;

public int Breadth { get { return _breadth; } } foo.Size++; Delegates / Events delegate-id MsgArrivedEventHandler. procedure division using value msg as string. end delegate. class-id a. working-storage section. 01 MsgArrivedEvent type MsgArrivedEventHandler event static. *> Delegates must be used with events method-id main static. procedure division. set MsgArrivedEvent to type Delegate::Combine(MsgArrivedEvent, new MsgArrivedEventHandler(self::myMsgArrivedEven tCallback)) as type MsgArrivedEventHandler invoke MsgArrivedEvent::Invoke("Test message") *> Throws exception if obj is null set MsgArrivedEvent to type Delegate::Remove(MsgArrivedEvent, new MsgArrivedEventHandler(self::myMsgArrivedEven tCallback)) as type MsgArrivedEventHandler invoke self::add_MsgArrivedEvent( new MsgArrivedEventHandler(self::My_MsgArrivedEve ntCallback)) invoke MsgArrivedEvent::Invoke("Test message 2") *> Throws exception if obj is null end method.

method-id myMsgArrivedEventCallback static. procedure division using value str as string. display str end method. end class a. Managed COBOL can also handle anonymous delegates (delegates to anonymous methods) via delegate constructors. delegate void MsgArrivedEventHandler(string message); event MsgArrivedEventHandler MsgArrivedEvent; // Delegates must be used with events in C# MsgArrivedEvent += new MsgArrivedEventHandler(My_MsgArrivedEven tCallback); // Throws exception if obj is null MsgArrivedEvent("Test message"); MsgArrivedEvent -= new MsgArrivedEventHandler(My_MsgArrivedEven tCallback); using System.Windows.Forms; Button MyButton = new Button(); MyButton.Click += new System.EventHandler(MyButton_Click); private void MyButton_Click(object sender, System.EventArgs e) { MessageBox.Show(this, "Button was clicked", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information); } //There is no delegate concept in Java //The right-side C# program may be mimicked //with reflection technology.

Iterators class-id sillyCount. working-storage section. 01 c binary-long value 1 static. method-id main static.

local-storage section. 01 i binary-long. procedure division using value cmds as string occurs any. *> Use perform to loop over an iterator perform varying i through self::doCount() display i end-perform end method. *> Create an iterator by defining a member as an iterator *> Using iterator-id instead of method-id iterator-id doCount static. *> The return value if the iterator is defined using the *> yielding verb procedure division yielding j as binary- long. perform until false add 1 to c move c to j *> Until the iterator is stopped, it will yield on *> a goback verb goback *> then start again directly after the goback *> on the next invocation of the iterator multiply c by 10 giving j if c < 50 goback else *> Stop iterator means the next goback will class SillyCount { static int c = 1; static void Main(string[] args) { // Use foreach to loop through an iterator foreach(int i in doCount()) { System.Console.WriteLine(i); } } // C# lacks specific syntax to mark a method as an iterator // you have to create a method with the correct concrete form // of the IEnumerable interface and then use the yield return // syntax inside the method.

static IEnumerable doCount() { while (true) { c++; // C# uses an implicit return 'variable' rather than // the named one in COBOL.

Yield return returns // the value as the current value of the iterator yield return c; // then starts immediately after the // yield return on the next invocation of // the iterator if (c < 50) { yield return c * 50; In Java there is no YIELD feature, so the iterator implementation has to take care of state. Sample to follow...

*> stop the iterator stop iterator goback end-if end-perform *> COBOL will implicitly stop iterator at the *> end of the iterator definition. *> In this example – the code never gets here. end iterator. end class. } else { // yield break marks the end of the iterator yield break; } } } } Generics - Consuming *> Consuming a generic method via type inference 01 result as type Tuple[binary-long binary- long].

*> Parameters are used to infer type set result to type Tuple::Create(1, 2) *> Consuming a generic collection 01 x type List[string] value new List[string].

01 i binary-long. 01 val string. procedure division. perform varying i from 0 by 1 until i greater than 100 invoke x::Add(i::ToString) end-perform perform varying val through x display val end-perform // Consuming a generic method via type inference System.Tuple result; // Parameters are used to infer type result = new System.Tuple.Create(1, 2); //Consuming a generic collection List x = new List(); int i; for(i=0; i Generic class class-id Point3D using T. *> With constraints class-id Point3D using T. constraints. constrain T implements type IComputable. *> Generic interface interface-id IComputable using T.

*> Generic method method-id MakePoint3D static public using T. procedure division using value x as T y as T z as T returning ret as type Point3D[T]. *> With constraints method-id MakePoint3D static public using T. constraints.

constrain T implements type IComputable. *> Generic value type valuetype-id container using T Y. 01 a T public. 01 b Y public. end valuetype. *> With constraints valuetype-id container using T Y. constraints. constrain T implements type IComputable. *> Generic iterator, use a parameterised class class-id a using T. iterator-id itg static. 01 val binary-long value 1. procedure division using value x as T yielding y as T. perform until val = 50 add 1 to val set y to x *> Just for example! goback end-perform end iterator. end class. *> To use, parameterise the class perform varying thg through type a[string]::itg("Dog") display thg end-perform // Generic class class Point3D // Generic class with constraints class Point3D_c where T : IComputable // Generic interface interface IComputable // Generic method public static Point3D MakePoint3D(T x, T y, T z) { return new Point3D(x, y, z); } // Generic method with constraints public static void MakePoint3D(T x, T y, T z) where T : IComputable { return new Point3D(x, y, z); } // Generic value type struct container { public T a; public Y b; } // Generic value type with constraints struct container where T : IComputable // Generic iterator, use a parameterised class class a { public static IEnumerable itg(T x) { int val = 1; while (val < 50) { val++; yield return x; } } } // Using generic iterator foreach (string dog in a.itg("Dog")) System.Console.WriteLine(dog); // Generic class class Point3D // Generic class with constraints class Point3D_c //Generic interface interface IComputable // Generic method public static Point3D MakePoint3D(T x, T y, T z) { return new Point3D(x, y, z); } // Generic method with constraints public static Point3D MakePoint3D(T x, T y, T z) { return new Point3D(x, y, z); } // No value type in Java, so generic simple class instead class container { public T a; public Y b; } // No value type in Java, so simple generic class with constraints class container // Generic iterator, use a parameterised class class a { public static T itg(T x) { int val = 1; while (val < 50) { val++; return x; } } } for (String dog : a) System.out.println(dog); Synchronization / Locking *> Synchronize on an object's monitor, in this case *> the current object sync on self *> The code here is synchronised end-sync // Synchronize on an object's monitor, in this case // the current object lock (this) { // The code here is synchronised // Synchronize on an object's monitor, in this case // the current object synchronized (this) { // The code here is synchronised