| 1 | = Cobra Code Examples = |
| 2 | |
| 3 | Some highlights of Cobra code and syntax ( on .Net) |
| 4 | |
| 5 | Here are the cobra code samples for the same items for a |
| 6 | [http://www.harding.edu/fmccown/vbnet_csharp_comparison.html VB and C# comparison]. |
| 7 | |
| 8 | == Program Structure == |
| 9 | |
| 10 | {{{ |
| 11 | #!cobra |
| 12 | |
| 13 | #use System # already defaulted in |
| 14 | |
| 15 | namespace Hello |
| 16 | class HelloWorld |
| 17 | def main is shared |
| 18 | name = "Cobra" |
| 19 | |
| 20 | args = CobraCore.commandLineArgs |
| 21 | # See if an argument was passed from the command line |
| 22 | # (first arg is progname) |
| 23 | if args.count == 2 |
| 24 | name = args[1] |
| 25 | |
| 26 | Console.writeLine("Hello, " + name + "!") |
| 27 | #print "Hello, [name]!" |
| 28 | }}} |
| 29 | |
| 30 | == Comments == |
| 31 | {{{ |
| 32 | #!cobra |
| 33 | |
| 34 | # Single line comment |
| 35 | /# Multiple |
| 36 | lines #/ |
| 37 | |
| 38 | # <summary>XML comments on single line</summary> |
| 39 | /# <summary>XML comments on multiple lines</summary> #/ |
| 40 | }}} |
| 41 | |
| 42 | |
| 43 | == Data Types == |
| 44 | These are as per .Net (using .Net naming rather than C#) |
| 45 | {{{ |
| 46 | #!cobra |
| 47 | # Value Types |
| 48 | bool |
| 49 | uint8 # byte |
| 50 | char |
| 51 | int16, uint16, int, uint, int64, uint64 # short, ushort, int, uint, long, ulong |
| 52 | float, float32, float64 #float, double |
| 53 | Decimal |
| 54 | DateTime #(not a built-in C# type) |
| 55 | Struct |
| 56 | Enum (enumerations) |
| 57 | |
| 58 | #Reference Types |
| 59 | Object |
| 60 | String |
| 61 | arrays |
| 62 | Sigs/Delegates |
| 63 | |
| 64 | #Initializing ( the explicit typing (clause 'as ????' ) is optional, types are inferred from initialisation) |
| 65 | correct as bool = true |
| 66 | b as uint8 = 0x2A # hex |
| 67 | person as Object? = nil |
| 68 | name as String = "Dwight" |
| 69 | grade as char = c'B' |
| 70 | today as DateTime= DateTime.parse("12/31/2010 12:15:00 PM") |
| 71 | amount as decimal = 35.99 |
| 72 | gpa as float = 2.9f |
| 73 | pi as float64 = 3.14159265_f64 |
| 74 | lTotal as int64 = 123456_i64 |
| 75 | sTotal as int16 = 123 |
| 76 | usTotal as uint16 = 123 |
| 77 | uiTotal as uint = 123 # or 123u |
| 78 | ulTotal as uint64 = 123 # or 123u64 |
| 79 | |
| 80 | #Nilable Types |
| 81 | x as int? = nil |
| 82 | |
| 83 | #Anonymous Types |
| 84 | # Havent worked out how Cobra handle these examples yet... |
| 85 | #var stu = new {Name = "Sue", Gpa = 3.5} |
| 86 | #var stu2 = new {Name = "Bob", Gpa = 2.9} # no Key equivalent |
| 87 | |
| 88 | #Implicitly Typed Local Variables |
| 89 | s = "Hello!" |
| 90 | nums = @[ 1, 2, 3 ] #init from array literal |
| 91 | hero = SuperHero("Batman") |
| 92 | |
| 93 | #Type Information |
| 94 | x as int? = 0 # Nilable int |
| 95 | Console.writeLine(x.getType) # Prints System.Int32 |
| 96 | Console.writeLine(sharp'typeof(int)') # Prints System.Int32 |
| 97 | Console.writeLine(x.getType.name) # prints Int32 |
| 98 | |
| 99 | #Type Conversion / Casting |
| 100 | d = 3.5f |
| 101 | i = Convert.toInt32(d) # Set to 4 (rounds) |
| 102 | i1 as int = d to int # set to 3 (truncates decimal) |
| 103 | |
| 104 | }}} |
| 105 | |
| 106 | == Constants == |
| 107 | {{{ |
| 108 | #!cobra |
| 109 | const MAX_STUDENTS as int = 25 |
| 110 | |
| 111 | # Can set to a const or var; may be initialized in a constructor |
| 112 | var MIN_DIAMETER as float is readonly= 4.93f |
| 113 | }}} |
| 114 | |
| 115 | |
| 116 | == Enumerations == |
| 117 | {{{ |
| 118 | #!cobra |
| 119 | enum Action |
| 120 | Start, Stop, Rewind, Forward |
| 121 | |
| 122 | enum Status |
| 123 | Flunk = 50 |
| 124 | Pass = 70 |
| 125 | Excel = 90 |
| 126 | |
| 127 | a = Action.Stop |
| 128 | if a <> Action.Start |
| 129 | Console.WriteLine(a + " is " + (int) a); # Prints "Stop is 1" |
| 130 | |
| 131 | Console.writeLine(Status.Pass to int) # Prints 70 |
| 132 | Console.writeLine(Status.Pass) # Prints Pass |
| 133 | }}} |
| 134 | |
| 135 | == Operators == |
| 136 | {{{ |
| 137 | #!cobra |
| 138 | |
| 139 | #Comparison |
| 140 | == < > <= >= <> |
| 141 | |
| 142 | # Arithmetic |
| 143 | + - * / |
| 144 | % (mod) |
| 145 | / (integer division if both operands are ints) |
| 146 | Math.Pow(x, y) |
| 147 | |
| 148 | #Assignment |
| 149 | = += -= *= /= %= &= |= ^= <<= >>= |
| 150 | # +=1 -=1 # ++, -- No post increment/decrement |
| 151 | |
| 152 | #Bitwise |
| 153 | & | ^ ~ << >> |
| 154 | |
| 155 | #Logical |
| 156 | and or not |
| 157 | #Note: and and or perform short-circuit logical evaluations |
| 158 | |
| 159 | #String Concatenation |
| 160 | + |
| 161 | |
| 162 | }}} |
| 163 | |
| 164 | == Choices == |
| 165 | {{{ |
| 166 | #!cobra |
| 167 | |
| 168 | # Nil-coalescing operator |
| 169 | x = y ? 5 # if y != null then x = y, else x = 5 |
| 170 | |
| 171 | # non nil coalescing |
| 172 | x = y ! y.parseIt # if y nil x = nil else x = y.parseIt() |
| 173 | |
| 174 | # Ternary/Conditional operator |
| 175 | greeting = if(age < 20, "What's up?", "Hello") |
| 176 | |
| 177 | if age < 20 |
| 178 | greeting = "What's up?" |
| 179 | else |
| 180 | greeting = "Hello" |
| 181 | |
| 182 | # Multiple statements must be indented following |
| 183 | if x <> 100 and y < 5 |
| 184 | x *= 5 |
| 185 | y *= 2 |
| 186 | |
| 187 | |
| 188 | # braces not needed around condition expressions unless complicated |
| 189 | if x > 5 |
| 190 | x *= y |
| 191 | else if x == 5 or y % 2 == 0 |
| 192 | x += y |
| 193 | else if x < 10 |
| 194 | x -= y |
| 195 | else |
| 196 | x /= y |
| 197 | |
| 198 | # alternatively (1 liners) |
| 199 | if x > 5, x *= y |
| 200 | else if x == 5 or y % 2 == 0, x += y |
| 201 | else if x < 10, x -= y |
| 202 | else, x /= y |
| 203 | |
| 204 | # indented action blocks, breaks not needed |
| 205 | case color # Must be integer, character, enumeration or string |
| 206 | on "pink" or "red" #constants |
| 207 | r++ |
| 208 | on "blue" |
| 209 | b++ |
| 210 | on "green" |
| 211 | g++ |
| 212 | else |
| 213 | other++ |
| 214 | |
| 215 | # 1 liners |
| 216 | case color |
| 217 | on 'pink' or 'red', r++ |
| 218 | on 'blue', b++ |
| 219 | on 'green', g++ |
| 220 | else, other++ |
| 221 | }}} |
| 222 | |
| 223 | == Loops == |
| 224 | {{{ |
| 225 | #!cobra |
| 226 | # re-test Loops: |
| 227 | |
| 228 | # no "until" keyword |
| 229 | while c < 10 |
| 230 | c += 1 |
| 231 | |
| 232 | |
| 233 | for c in 2 : 11 : 2 # start: stop : step |
| 234 | Console.writeLine(c) |
| 235 | #print c |
| 236 | |
| 237 | #Post-test Loop: |
| 238 | post while c < 10 |
| 239 | c += 1 |
| 240 | |
| 241 | |
| 242 | # Array or collection looping |
| 243 | names = {"Fred", "Sue", "Barney"} |
| 244 | for s in names |
| 245 | Console.writeLine(s) |
| 246 | # print s |
| 247 | |
| 248 | |
| 249 | # Breaking out of loops |
| 250 | i = 0 |
| 251 | while true |
| 252 | if i == 5 |
| 253 | break |
| 254 | i += 1 |
| 255 | |
| 256 | # Continue to next iteration |
| 257 | for i in 0 : 5 |
| 258 | if i < 4 |
| 259 | continue |
| 260 | print i #same as Console.writeLine(i) # Only prints 4 |
| 261 | |
| 262 | }}} |
| 263 | |
| 264 | |
| 265 | == Arrays == |
| 266 | |
| 267 | #Preference is for (typed) collections rather than arrays |
| 268 | |
| 269 | {{{ |
| 270 | #!cobra |
| 271 | nums as int[] = @[1, 2, 3] |
| 272 | for i in 0 : nums.length |
| 273 | Console.writeLine(nums[i]) |
| 274 | |
| 275 | |
| 276 | # 5 is the size of the array |
| 277 | names as String[]= String[](5) |
| 278 | names[0] = 'David'; |
| 279 | names[5] = "Bobby"; # Throws System.IndexOutOfRangeException |
| 280 | |
| 281 | # Add two elements, keeping the existing values |
| 282 | Array.resize(ref names, 7) |
| 283 | |
| 284 | # multi dim and jagged arrays not well supported (use Collections) |
| 285 | twoD = sharp'new float[rows, cols]' |
| 286 | twoD[2,0] = 4.5f |
| 287 | |
| 288 | jagged as int[][] = sharp'new int[3][] { new int[5], new int[2], new int[3] }' |
| 289 | jagged[0][4] = 5 |
| 290 | }}} |
| 291 | |
| 292 | As a collection |
| 293 | |
| 294 | {{{ |
| 295 | #!cobra |
| 296 | nums = [1, 2, 3] |
| 297 | for i in 0 : nums.count |
| 298 | print nums[i] |
| 299 | |
| 300 | # 5 is the size of the array |
| 301 | names = List(5) |
| 302 | names[0] = "David"; |
| 303 | names[5] = "Bobby"; # Throws System.IndexOutOfRangeException |
| 304 | |
| 305 | }}} |
| 306 | |
| 307 | == Functions == |
| 308 | {{{ |
| 309 | #!cobra |
| 310 | |
| 311 | # Pass by value (in, default), in/out reference (inout), and reference (out) |
| 312 | def testFunc(x as int, y as inout int, z as out int) |
| 313 | x += 1 |
| 314 | y += 1 |
| 315 | z = 5 |
| 316 | |
| 317 | # Accept variable number of arguments |
| 318 | def sum(nums as vari int) as int |
| 319 | sum as int = 0 |
| 320 | for i in nums |
| 321 | sum += i |
| 322 | return sum |
| 323 | |
| 324 | def sayHello(name as String, prefix = "") |
| 325 | Console.writeLine("Greetings, " + prefix + " " + name) |
| 326 | |
| 327 | def main |
| 328 | |
| 329 | a = 1 |
| 330 | b = 1 |
| 331 | c as int # c doesn't need initializing |
| 332 | .testFunc(a, inout b, out c) |
| 333 | Console.writeLine("{0} {1} {2}", a, b, c) # 1 2 5 |
| 334 | assert c == 5 and b == 2 |
| 335 | |
| 336 | total = .sum(4, 3, 2, 1) # returns 10 |
| 337 | assert total == 10 |
| 338 | |
| 339 | |
| 340 | .sayHello("Strangelove", "Dr.") |
| 341 | .sayHello("Mom") |
| 342 | }}} |
| 343 | |
| 344 | |
| 345 | == Strings == |
| 346 | {{{ |
| 347 | #!cobra |
| 348 | |
| 349 | # Escape sequences |
| 350 | # \r # carriage-return |
| 351 | # \n # line-feed |
| 352 | # \t # tab |
| 353 | # \\ # backslash |
| 354 | |
| 355 | # Can use either " or ' to delimit String literals |
| 356 | # preference is for ' unless string contains ', then use " |
| 357 | |
| 358 | # String concatenation |
| 359 | school = "Harding\t" |
| 360 | school = school + "University" # school is "Harding (tab) University" |
| 361 | school += "University" # Same thing |
| 362 | school += 'University' # Same thing |
| 363 | |
| 364 | # Chars |
| 365 | letter = school[0] # letter is H |
| 366 | letter = 'Z' # letter is Z |
| 367 | letter = Convert.toChar(65) # letter is A |
| 368 | letter = 65 to Char # same thing |
| 369 | word = school.toCharArray # word holds Harding |
| 370 | |
| 371 | # String literal |
| 372 | string filename = r'c:\temp\x.dat' # Same as "c:\\temp\\x.dat" |
| 373 | |
| 374 | # String comparison |
| 375 | mascot = 'Bisons' # or mascot = "Bisons" |
| 376 | if mascot == "Bisons" # true |
| 377 | if mascot.equals('Bisons') # true |
| 378 | if mascot.toUpper.equals('BISONS') # true |
| 379 | if mascot.compareTo('Bisons') == 0 # true |
| 380 | |
| 381 | # String matching - No Like equivalent, use Regex |
| 382 | |
| 383 | |
| 384 | # Substring |
| 385 | s = mascot.substring(2, 3) # s is "son" |
| 386 | |
| 387 | # Replacement |
| 388 | s = mascot.replace('sons', 'nomial') # s is "Binomial" |
| 389 | |
| 390 | # Split |
| 391 | names = 'Michael,Dwight,Jim,Pam' |
| 392 | parts = names.split(','.toCharArray()) # One name in each slot |
| 393 | #or |
| 394 | parts = names.split([ c',']) |
| 395 | |
| 396 | # Date to string |
| 397 | DateTime dt = DateTime(1973, 10, 12) |
| 398 | s = dt.toString('MMM dd, yyyy') # Oct 12, 1973 |
| 399 | |
| 400 | # int to string |
| 401 | x = 2 |
| 402 | y = x.toString() # y is "2" |
| 403 | # string to int |
| 404 | x = Convert.toInt32('-5') # x is -5 |
| 405 | |
| 406 | # Mutable string |
| 407 | buffer = System.Text.StringBuilder('two ') |
| 408 | buffer.append('three ') |
| 409 | buffer.insert(0, 'one ') |
| 410 | buffer.replace('two', 'TWO') |
| 411 | Console.writeLine(buffer) # Prints "one TWO three" |
| 412 | |
| 413 | }}} |
| 414 | |
| 415 | |
| 416 | == Regular Expressions == |
| 417 | {{{ |
| 418 | #!cobra |
| 419 | use System.Text.RegularExpressions |
| 420 | |
| 421 | |
| 422 | # Match a string pattern |
| 423 | r = Regex(r'j[aeiou]h?. \d:*', RegexOptions.IgnoreCase | RegexOptions.Compiled) |
| 424 | if r.match('John 3:16').success # true |
| 425 | Console.writeLine("Match") |
| 426 | |
| 427 | |
| 428 | # Find and remember all matching patterns |
| 429 | s = 'My number is 305-1881, not 305-1818.' |
| 430 | r = Regex(r'(\\d+-\\d+)') |
| 431 | # Matches 305-1881 and 305-1818 |
| 432 | m as Match = r.match(s) |
| 433 | while m.success |
| 434 | #Console.writeLine("Found number: " + m.groups[1].toString + " at position " + m.groups[1].index.toString) |
| 435 | print 'Found number: [m.groups[1]] at position [m.groups[1].index]' |
| 436 | m = m.nextMatch to ! |
| 437 | |
| 438 | |
| 439 | # Remember multiple parts of matched pattern |
| 440 | r = Regex(r'(\d\d):(\d\d) (am|pm)') |
| 441 | m = r.match("We left at 03:15 pm.") |
| 442 | if m.success |
| 443 | Console.writeLine("Hour: " + m.groups[1].toString) # 03 |
| 444 | Console.writeLine("Min: " + m.groups[2].toString) # 15 |
| 445 | Console.writeLine("Ending: " + m.groups[3].toString) # pm |
| 446 | |
| 447 | # Replace all occurrances of a pattern |
| 448 | r = Regex(r'h\\w+?d', RegexOptions.IgnoreCase) |
| 449 | s = r.replace("I heard this was HARD!", "easy") # I easy this was easy! |
| 450 | |
| 451 | # Replace matched patterns |
| 452 | s = Regex.replace('123 < 456', r'(\d+) . (\d+)', '$2 > $1') # 456 > 123 |
| 453 | |
| 454 | # Split a string based on a pattern |
| 455 | names = 'Michael, Dwight, Jim, Pam' |
| 456 | r = Regex(r',\s*') |
| 457 | parts = r.split(names) # One name in each slot |
| 458 | |
| 459 | }}} |
| 460 | |
| 461 | == Exceptions == |
| 462 | {{{ |
| 463 | #!cobra |
| 464 | |
| 465 | # Throw an exception |
| 466 | up = Exception('Something is really wrong.') |
| 467 | throw up # ha ha |
| 468 | |
| 469 | # Catch an exception |
| 470 | try |
| 471 | y = 0 |
| 472 | x = 10 / y |
| 473 | catch ex as Exception # Argument is optional, no "When" keyword |
| 474 | Console.writeLine(ex.message) |
| 475 | finally |
| 476 | Microsoft.VisualBasic.Interaction.beep |
| 477 | |
| 478 | }}} |
| 479 | |
| 480 | == Namespaces == |
| 481 | |
| 482 | {{{ |
| 483 | #!cobra |
| 484 | |
| 485 | namespace Harding.Compsci.Graphics |
| 486 | ... |
| 487 | |
| 488 | # or |
| 489 | |
| 490 | namespace Harding |
| 491 | namespace Compsci |
| 492 | namespace Graphics |
| 493 | ... |
| 494 | |
| 495 | use Harding.Compsci.Graphics |
| 496 | }}} |
| 497 | |
| 498 | == Classes and Interfaces == |
| 499 | {{{ |
| 500 | #!cobra |
| 501 | |
| 502 | ## Access Modifiers |
| 503 | public # default |
| 504 | private |
| 505 | internal |
| 506 | protected |
| 507 | protected internal |
| 508 | |
| 509 | #Class Modifiers |
| 510 | abstract |
| 511 | shared |
| 512 | |
| 513 | #Method Modifiers |
| 514 | abstract |
| 515 | shared |
| 516 | virtual #default |
| 517 | |
| 518 | #No Module equivalent - just use static class |
| 519 | |
| 520 | # Partial classes |
| 521 | class Competition is partial |
| 522 | ... |
| 523 | |
| 524 | # Inheritance |
| 525 | class FootballGame inherits Competition |
| 526 | ... |
| 527 | |
| 528 | |
| 529 | # Interface definition |
| 530 | interface IAlarmClock |
| 531 | def ring # public returns void by default |
| 532 | pro currentDateTime as DateTime from var |
| 533 | } |
| 534 | |
| 535 | # Extending an interface |
| 536 | interface IAlarmClock inherits IClock |
| 537 | ... |
| 538 | } |
| 539 | |
| 540 | |
| 541 | # Interface implementation |
| 542 | class WristWatch implements IAlarmClock, ITimer |
| 543 | |
| 544 | def ring |
| 545 | Console.writeLine('Wake up!') |
| 546 | |
| 547 | pro triggerDateTime as DateTime from var |
| 548 | ... |
| 549 | }}} |
| 550 | |
| 551 | == Constructors and Destructors == |
| 552 | {{{ |
| 553 | #!cobra |
| 554 | |
| 555 | class SuperHero inherits Person |
| 556 | |
| 557 | var powerLevel as int is private |
| 558 | var name as String is private |
| 559 | |
| 560 | |
| 561 | # Default constructor |
| 562 | cue init |
| 563 | .powerLevel = 0 |
| 564 | .name = 'Super Bison' |
| 565 | |
| 566 | cue init(powerLevel as int) |
| 567 | base.init('Super Bison') # Call other constructor |
| 568 | .powerLevel = powerLevel |
| 569 | |
| 570 | cue init(name as String) |
| 571 | base.init(name) # Call base classes' constructor |
| 572 | .name = name |
| 573 | |
| 574 | cue init is shared |
| 575 | # Static constructor invoked before 1st instance is created |
| 576 | |
| 577 | cue finalize |
| 578 | # Destructor implicitly creates a Finalize method |
| 579 | }}} |
| 580 | |
| 581 | == Using Objects == |
| 582 | {{{ |
| 583 | #!cobra |
| 584 | |
| 585 | hero as SuperHero? = SuperHero() |
| 586 | |
| 587 | # No "With" but can use property initializers |
| 588 | hero = SuperHero(name = "SpamMan", powerLevel = 3) |
| 589 | |
| 590 | hero.defend("Laura Jones") |
| 591 | SuperHero.rest # Calling static method |
| 592 | |
| 593 | |
| 594 | hero2 = hero # Both reference the same object |
| 595 | hero2.name = 'WormWoman' |
| 596 | Console.writeLine(hero.name) # Prints WormWoman |
| 597 | |
| 598 | hero = nil # Free the object |
| 599 | |
| 600 | if hero == nil # or if not hero |
| 601 | hero = SuperHero() |
| 602 | |
| 603 | obj as Object = SuperHero() |
| 604 | if obj inherits SuperHero |
| 605 | Console.writeLine("Is a SuperHero object.") |
| 606 | |
| 607 | # Mark object for quick disposal |
| 608 | using reader as StreamReader = File.openText("test.txt") |
| 609 | line as String? |
| 610 | while (line = reader.readLine) <> nil |
| 611 | Console.writeLine(line) |
| 612 | |
| 613 | }}} |
| 614 | |
| 615 | == Structs == |
| 616 | {{{ |
| 617 | #!cobra |
| 618 | struct Student |
| 619 | var name as String |
| 620 | var gpa as float |
| 621 | |
| 622 | cue init(name as String, gpa as float) |
| 623 | .name = name |
| 624 | .gpa = gpa |
| 625 | |
| 626 | stu = Student("Bob", 3.5f) |
| 627 | stu2 = stu |
| 628 | |
| 629 | stu2.name = "Sue" |
| 630 | Console.writeLine(stu.name) # Prints Bob |
| 631 | Console.writeLine(stu2.name) # Prints Sue |
| 632 | }}} |
| 633 | |
| 634 | |
| 635 | == Properties == |
| 636 | {{{ |
| 637 | #!cobra |
| 638 | |
| 639 | |
| 640 | # Auto-implemented properties |
| 641 | pro name as String from var |
| 642 | get size as int from var # Set default value in constructor |
| 643 | |
| 644 | # Traditional property implementation |
| 645 | var name as String is private # private backing variable |
| 646 | #or |
| 647 | #var __name as String #private |
| 648 | #var _name as String #protected |
| 649 | |
| 650 | |
| 651 | pro Name as String |
| 652 | get |
| 653 | return .name |
| 654 | # return __name |
| 655 | set |
| 656 | .name = value |
| 657 | #__name =value |
| 658 | |
| 659 | # Read-only property |
| 660 | var powerLevel as int is private # private backing variable |
| 661 | get powerlevel from var |
| 662 | |
| 663 | #alternatively |
| 664 | var __powerLevel = 0 # inferred as type int, private |
| 665 | get powerlevel from var |
| 666 | |
| 667 | # Write-only property |
| 668 | var height as double is private # private backing variable |
| 669 | set height as double |
| 670 | .height = if(value < 0, 0, value) |
| 671 | |
| 672 | }}} |
| 673 | |
| 674 | == Generics == |
| 675 | {{{ |
| 676 | #!cobra |
| 677 | # Enforce accepted data type at compile-time |
| 678 | numbers = List<of int>() |
| 679 | numbers.add(2) |
| 680 | numbers.add(4) |
| 681 | displayList<of int>(numbers) |
| 682 | |
| 683 | # Function can display any type of List |
| 684 | def displayList<of T>(List<of T> list) |
| 685 | for item as T in list |
| 686 | Console.writeLine(item) |
| 687 | |
| 688 | # Class works on any data type |
| 689 | class SillyList<of T> |
| 690 | list as T[] = T[](10) |
| 691 | rand as Random = Random() |
| 692 | |
| 693 | public void add(item as T) |
| 694 | list[rand.next(10)] = item |
| 695 | |
| 696 | public getItem as T |
| 697 | return list[rand.next(10)] |
| 698 | } |
| 699 | |
| 700 | # Limit T to only types that implement IComparable |
| 701 | def maximum<of T>(items as vari T) where T must be IComparable<of T> |
| 702 | max as T = items[0] |
| 703 | for item in items |
| 704 | if item.compareTo(max) > 0 |
| 705 | max = item |
| 706 | return max |
| 707 | }}} |
| 708 | |
| 709 | == Delegates and Lambda Expresssions == |
| 710 | {{{ |
| 711 | #!cobra |
| 712 | sig HelloDelegate(s as String) # returns void |
| 713 | |
| 714 | def sayHello(s as String) |
| 715 | Console.writeLine('Hello, ' + s) |
| 716 | |
| 717 | # C# 1.0 delegate syntax with named method |
| 718 | hello as HelloDelegate = ref .sayHello |
| 719 | hello('World') # Or hello.Invoke('World') |
| 720 | |
| 721 | # C# 2.0 delegate syntax with anonymous method |
| 722 | # method body indented on lines following do(args) |
| 723 | hello2 as HelloDelegate = do(s as String) |
| 724 | Console.WriteLine('Hello, ' + s) |
| 725 | |
| 726 | hello2("World") |
| 727 | |
| 728 | # C# 3.0 delegate syntax with lambda expression |
| 729 | HelloDelegate hello3 as HelloDelegate = do(s as string)=Console.writeLine('Hello, ' + s) |
| 730 | hello3("World") |
| 731 | |
| 732 | # Use Func<in T, out TResult> delegate to call Uppercase |
| 733 | convert as Func<of String, of String> = ref .uppercase |
| 734 | Console.writeLine(convert("test")) |
| 735 | |
| 736 | def uppercase(s as String) |
| 737 | return s.toUpper |
| 738 | |
| 739 | # Declare and invoke Func using a lambda expression |
| 740 | Console.WriteLine( Func<of int, of int>do(num as int) = num + 1)(2)) |
| 741 | |
| 742 | # Pass lamba expression as an argument |
| 743 | TestValues(do(x, y) = x % y == 0) |
| 744 | |
| 745 | void TestValues(Func<of int, of int, of bool> f) |
| 746 | if f(8, 4) |
| 747 | Console.writeLine("true") |
| 748 | else |
| 749 | Console.writeLine("false") |
| 750 | |
| 751 | }}} |
| 752 | |
| 753 | |
| 754 | == Events == |
| 755 | {{{ |
| 756 | #!cobra |
| 757 | sig MsgArrivedEventHandler(message as String) |
| 758 | |
| 759 | event MsgArrivedEvent as MsgArrivedEventHandler |
| 760 | |
| 761 | |
| 762 | # listen EVENT_NAME, METHOD_NAME |
| 763 | listen MsgArrivedEvent, MsgArrivedEventHandler(.my_MsgArrivedEventCallback) |
| 764 | raise MsgArrivedEvent, "Test message" # Throws exception if obj is null |
| 765 | #ignore EVENT_NAME, METHOD_NAME |
| 766 | ignore MsgArrivedEvent, MsgArrivedEventHandler(.my_MsgArrivedEventCallback) |
| 767 | |
| 768 | |
| 769 | using System.Windows.Forms |
| 770 | |
| 771 | myButton = Button() |
| 772 | listen myButton.click, System.EventHandler(ref .myButton_Click) |
| 773 | |
| 774 | def myButton_Click(sender as Object, e as System.EventArgs ) |
| 775 | MessageBox.show(this, "Button was clicked", "Info", |
| 776 | MessageBoxButtons.OK, MessageBoxIcon.Information) |
| 777 | |
| 778 | }}} |
| 779 | |
| 780 | == LINQ == |
| 781 | TBI |
| 782 | {{{ |
| 783 | #!cobra |
| 784 | }}} |
| 785 | |
| 786 | == Attributes == |
| 787 | {{{ |
| 788 | #!cobra |
| 789 | # Attribute can be applied to anything |
| 790 | class IsTestedAttribute inherits Attribute |
| 791 | pass |
| 792 | |
| 793 | # Attribute can only be applied to classes or structs |
| 794 | class AuthorAttribute inherits Attribute |
| 795 | has AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct) |
| 796 | |
| 797 | pro name as String from var |
| 798 | pro version as int from var |
| 799 | |
| 800 | cue init(name as String ) |
| 801 | .name = name; |
| 802 | .version = 0; |
| 803 | } |
| 804 | } |
| 805 | |
| 806 | class Shape |
| 807 | has Author("Sue", version = 3) |
| 808 | |
| 809 | def move |
| 810 | has IsTested |
| 811 | // Do something... |
| 812 | |
| 813 | }}} |
| 814 | |
| 815 | |
| 816 | == Console I/O == |
| 817 | {{{ |
| 818 | #!cobra |
| 819 | |
| 820 | Console.write("What's your name? ") |
| 821 | name as String = Console.readLine |
| 822 | Console.write('How old are you? ') |
| 823 | age as int = Convert.toInt32(Console.readLine) |
| 824 | Console.writeLine("{0} is {1} years old.", name, age) |
| 825 | # or |
| 826 | Console.writeLine(name + " is " + age + " years old.") |
| 827 | |
| 828 | c as int = Console.read # Read single char |
| 829 | Console.writeLine(c) # Prints 65 if user enters "A" |
| 830 | |
| 831 | # alternatively |
| 832 | |
| 833 | print "What's your name? " stop |
| 834 | name = Console.readLine |
| 835 | print 'How old are you? ' stop |
| 836 | age = Convert.toInt32(Console.readLine) |
| 837 | print '[name] is [age] years old.' |
| 838 | # or |
| 839 | print String.format('{0} is {1} years old.', name, age) |
| 840 | |
| 841 | c as int = Console.read # Read single char |
| 842 | print c # Prints 65 if user enters "A" |
| 843 | }}} |
| 844 | |
| 845 | == File I/O == |
| 846 | {{{ |
| 847 | #!cobra |
| 848 | #use System.IO # already autoloaded |
| 849 | |
| 850 | # Write out to text file |
| 851 | writer as StreamWriter = File.createText(r'c:\myfile.txt') |
| 852 | writer.writeLine('Out to file.') |
| 853 | writer.close |
| 854 | |
| 855 | # Read all lines from text file |
| 856 | reader as StreamReader = File.openText(r'c:\myfile.txt') |
| 857 | line = reader.readLine |
| 858 | while line |
| 859 | Console.writeLine(line) |
| 860 | line = reader.readLine |
| 861 | reader.close |
| 862 | |
| 863 | # Write out to binary file |
| 864 | str as String = "Text data" |
| 865 | num = 123 |
| 866 | binWriter = BinaryWriter(File.openWrite(r'c:\myfile.dat')) |
| 867 | binWriter.write(str) |
| 868 | binWriter.write(num) |
| 869 | binWriter.close |
| 870 | |
| 871 | # Read from binary file |
| 872 | binReader = BinaryReader(File.openRead(r'c:\myfile.dat')) |
| 873 | str = binReader.readString |
| 874 | num = binReader.readInt32 |
| 875 | binReader.close |
| 876 | }}} |
| 877 | |
| 878 | |
| 879 | Return to wiki:WikiStart |