Skip to content

Differences with Csharp

Nathaniel Sabanski edited this page Jan 20, 2016 · 19 revisions

Added by dholton dholton

This page notes some differences between C# and boo.

C# to Boo Converter

The easiest way to see how code in boo differs from C# is to use the C# to boo converter included in the Boo AddIn For SharpDevelop.

The converter is also accessible online via a webform here: http://developer.sharpdevelop.net/codeconvert.net

While viewing a C# file in SharpDevelop, you can select from the menu: Tools -> Convert C# to boo. Or you can convert an entire C# project at once by right-clicking on the project icon and selecting: Convert -> C# to boo. Note, however, the converter is still new and in development.

The converter will convert C# to legal boo code, but it will not show you the simplest way to write that code. For example, instead of "System.Console.WriteLine error ", in boo you can simply say "print x". And many times the type will be declared "x as int" when it is unnecessary since the type can be inferred by the boo compiler: "x = 3" or "m = MyClass()".

C# vs. Boo Syntax Examples

Here is a table noting some diffences between C# and boo, based on this table from the Nemerle programming language site. See also the C# language specification.

Expressions

C# Boo Remarks
``` int x = 3; string y = "foo"; FooBarQux fbq = make_fbq (); ``` ```boo x = 3 y = "foo" fbq = make_fbq() ``` Types are inferred, no semicolons needed
``` expr_1 = expr_2 = expr_3; ``` ```boo expr_1 = expr_2 = expr_3 ```
``` Class c = new Class (params); ``` ```boo c = Class(params) ``` No "new" keyword required
``` Class[] c = new Class [size] ``` ```boo c = array(Class, size) ``` See Lists and Arrays
``` GenericClass c = new GenericClass(); ``` ```boo c = GenericClass[of int]() ``` See Generics
``` Type[] l = new Type[] { expr_1, expr_1, ..., expr_n } ``` ```boo l = (expr_1, expr_1, ..., expr_n) ``` Types are inferred when you use arrays
``` if (cond) return foo; do_something (); return bar; ``` ```boo if cond: return foo //You can also say: return foo if cond do_something() return bar ```
``` if (cond) answer = 42; ``` ```boo if cond: answer = 42 //or answer = 42 if cond ```
``` if (!cond) answer = 42; ``` ```boo answer = 42 if not cond ```
``` try ... catch (FooException e) { ... } catch (BarException e) { ... } ``` ```boo try: ... except e as FooException: ... except e as BarException: ... ```
``` try { foo (); bar (); } catch (Exception e) { baz (); } finally { qux (); } ``` ```boo try: foo() bar() except e: baz() ensure: qux() ```
``` throw new System.ArgumentException ("foo"); ``` ```boo raise System.ArgumentException("foo") ``` Use "raise" to generate an exception.
``` type t = ((type) expr) ``` ```boo t = expr cast type //or //null if cast fails: t = expr as type ``` See Casting Types
``` using System.Windows.Forms; Button button = control as Button; if (button != null) ... else ... ``` ```boo import System.Windows.Forms button = control as Button if button != null: ... else: ... ```
``` using System; using SWF = System.Windows.Forms; using System.Xml; ... Console.WriteLine ("foo"); SWF.Form x = new SWF.Form (); XmlDocument doc = new XmlDocument (); ``` ```boo import System import System.Windows.Forms as SWF import System.Xml

print "foo" x = SWF.Form() doc = XmlDocument()

</td>
<td> You can create aliases for namespaces.
<br><br> Also use print instead of console.writeline. </td> </tr>
<tr><td>

x++; ++x;

</td>
<td>
```boo
x++
++x
``` readonly int X = 2; const int Y = 3; ``` ```boo final X = 2 static final Y = 3 ``` Read-only and constant fields.

Type definitions

C# Boo Remarks
``` static int foo (int x, string y) { ... } ``` ```boo static def foo(x as int, y as string) as int: ... ``` Use "def" for methods and functions.

Types are declared with the "as" keyword like VB.
``` class Foo : Bar { public Foo (int x) : base (x) { ... } } ``` ```boo class Foo (Bar): def constructor(x as int): super(x) ... ``` Illustrates a class with a superclass and a constructor
``` class Foo { int x; } ``` ```boo class Foo: x as int ``` a class with a field
``` class Foo { readonly int x; } ``` ```boo class Foo: final x as int ``` or else a "const" keyword may be added to boo
``` class C : I1, I2 { void I1.m () { ... } void I2.m () { ... } } ``` ```boo class C (I1, I2): def I1.m(): ... def I2.m(): ... ``` Implementing two interfaces that have

the same named method.

``` using System.Runtime.CompilerServices; class C { public object this [int i] { ... } [CSharp.IndexerName("MyItem")] public int this [string name] { ... } } ``` ```boo import System.Reflection

[DefaultMember("MyItem")] class A: private _val = (1,2,3,4)

MyItem(index as long) as int:
	get:
		return _val[index]
	set:
		_val[index] = value

a = A() print a[2] a[2] = 10 print a[2]

</td>
<td> Use the DefaultMember attribute. </td> </tr>
<tr>
<td>

char c = 'a';

</td>
<td>
```boo
c = char('a')
char() builtin
``` float v = 1.0f; ``` ```boo f = 1.0f //or f as single = 1.0 ``` Uses "single" instead of "float"

Miscellaneous Differences and Similarities

C# Boo Remarks
``` // A comment. /* A possibly multiline comment. */ ``` ```boo // A comment. /* A possibly multiline comment. */ # Another comment ``` C++ style commenting plus Python # comments
``` @"foo\bar" ``` ```boo """foo\bar""" ``` Quoted string literals.

Triple-quoted strings can span multiple lines, too.

Other Notes on Differences Between C# and Boo

These are some early notes from looking at the C# language specification.

Assigning multiple variables at once

In C#, you can assign a value to two variables at once like so:

int a, b = 1

In boo, however, "a, b" refers to a sequence. So you would instead use:

a = b = 1

Note also declaring the type is unnecessary because of boo's Type Inference.

Use "a, b" when unpacking multiple values. For example:

name = "First Last"
firstname, lastname = @/ /.Split(name)
print firstname, lastname

Also note in boo you can use the "print" statement instead of System.Console.WriteLine.

Buffer overflow checking

You can turn off overflow checking in boo like so:

try:
    checked:
        i = 100000
        i += 1000000000
        i += 1000000000
        i += 1000000000
except:
    print "did overflow i"

unchecked:
    j = 100000
    j += 1000000000
    j += 1000000000
    j += 1000000000
    print "didn't overflow j: $j"

Variable number of parameters.

static void F(params int[] args) {
      Console.WriteLine("# of arguments: {0}", args.Length);
      for (int i = 0; i < args.Length; i++)
      Console.WriteLine("\targs[{0}] = {1}", i, args[i]);
   }

Boo uses syntax similar to python:

def F(*args as (int)):
    print "# of arguments: $(len(args))"
    for arg in args:
        print arg

By reference and output parameters.

In C# you can pass types to functions by reference using "ref" or "out" keywords.

static void Swap(ref int a, ref int b) {
      int t = a;
      a = b;
      b = t;
   }
   ....
     Swap(ref x, ref y);

Boo supports the "ref" keyword, too, but not "out", which is unnecessary in boo.

def Swap(ref a as int, ref b as int):
      t = a
      a = b
      b = t
x = 1
y = 2
Swap(x,y)

Note though that in this particular sample, you can swap two values more easily like so:

x = 1
y = 2

x, y = y, x
print x, y //-> 2 1

As a more general alternative to by reference parameters, in boo you can also return multiple values from a function instead:

def Swap(a as int, b as int):
    return b, a

a, b = Swap(a, b)

Things in C# but not Boo

do..while loop

Boo doesn't have do..while or do..until loops like C# or VB.NET.

You can emulate them with "while true" loops.

unsafe code

static void WriteLocations(byte[] arr) {
      unsafe {
         fixed (byte* pArray = arr) {
            byte* pElem = pArray;
            for (int i = 0; i < arr.Length; i++) {
               byte value = *pElem;
               Console.WriteLine("arr[{0}] at 0x{1:X} is {2}",
               i, (uint)pElem, value);
               pElem++;
            }
         }
      }
   }
Clone this wiki locally