Nemerle入門Ⅴ～その他の機能～

Nemerleでの他のC#にもある機能を紹介します．
## Delegate
C\#と同じです．

```nemerle:delegate
delegate Foo (_ : int, _ : string) : void;
delegate Callback () : void;

def ff = Foo(fun(n, s) { ... });
```
## Event
C\#と同じです．

```nemerle:event
class Button {
  public event OnClick : Callback;
}

def b = Button ();
def my_cb = Callback(fun() { ... });
b.OnClick += my_cb;
b.OnClick -= my_cb;

b.OnClick += fun() { ... };
```

## out/ref
C\#と同じです．残念ながら`in`は実装されていません．

```nemerle:out_ref
someMethod(a, : ref int, b : out int) : int {
  a += 12;
  b = a * 2;
  a + b;
}

mutable a = 12;
mutable b : int;
someMethod(ref a, out b) |> WriteLine;
```

## Genericなメソッド
C\#と同じです．

```nemerle:generic_method
someMethod[T](n : T) : void {
  WriteLine(n);
} 

def i : int = 0
someMethod(i);
//or
someMethod[int](i);
```

## interface
C\#と同じ．

```nemerle:interface
using Nemerle.IO;

interface IPrintable {
  Print () : void;
}

class RefrigeratorNG : Refrigerator, IPrintable
{
  public Print () : void
  {
    printf ("I'm the refrigerator!\n")
  }

  public this ()
  {
  }
}

module RP {
  PrintTenTimes (p : IPrintable) : void
  {
    for (mutable i = 0; i < 10; ++i)
      p.Print ()
  }
  
  Main () : void
  {
    def refr = RefrigeratorNG ();
    PrintTenTimes (refr)
  }
}
```

## Indexer
どっちかというとVisualBasic寄り？

```nemerle:indexer
class Table {
  store : array [array [string]];
  public Item [row : int, column : int] : string
  {
    get {
      System.Console.WriteLine ($"get ($row, $column)");
      store[row][column]
    }
    set {
      System.Console.WriteLine ($"set ($row, $column)");
      store[row][column] = value
    }
  }
  public this ()
  {
    store = array (10);
    for (mutable i = 0; i < store.Length; ++i)
      store [i] = array (10);
  }
}

def t = Table ();
t[2, 3] = "foo";
t[2, 2] = t[2, 3] + "bar";

/* Output:
set (2, 3)
get (2, 3)
set (2, 2)
*/
```
## Enum
C\#と同じ．バリアントより早いと思います．

```nemerle:enum
enum Color {
  | Red
  | Green
  | Blue
}

def string_of_color (e) {
  match (e) {
    | Color.Red => "red"
    | Color.Green => "green"
    | Color.Blue => "blue"
  }
}
```
もちろん高度なことも

```nemerle:enum_ad
using System;

[FlagsAttribute]
enum Seasons {
  | Winter = 0b0001
  | Spring = 0b0010
  | Summer = 0b0100
  | Fall = 0b1000
  | Autumn = Fall
  | AllSeasons = Winter + Spring + Summer + Fall
}
 
def seasons = Seasons.Winter | Seasons.Fall;
Console.WriteLine ($"Seasons: $(seasons.ToString())");  //Seasons: Winter, Fall
```

## using
C\# 6と同様に`using System.Console`ができるように，静的クラスのusingができます．
もちろん，`using srw = System.Drawing`といったこともできます．

## using(IDisposable)
C\#と同じです．

```nemerle:using
using (sr = File.OpenText("test.txt")) {
  def line1 = sr.ReadLine();
  def line2 = sr.ReadLine();
  WriteLine($"line1 = $line1");
  WriteLine($"line2 = $line2");
}
```

## 演算子のオーバーロード
C\#よりも使える記号の制限が少ないです．

```nemerle:overload
class hoge {
  public n : int;
  public this(i : int) {
    n = i;
  }
  
  public static @<-< (x : hoge, y : hoge) {
    hoge(x.n + y.n);
  }
}

def a = hoge(12);
def b = hoge(22);
a <-< b > WriteLine;
```

## try-catch-finally
C\#と同じ感じですが，catchは何個もつけるのではなく，パターンマッチのような書式となります．

```nemerle:try
try {
 ...
} catch {
  | _ is DivideByZeroException => WriteLine("You divided valid number.")
  | _ is NotImplementedException => WriteLine("The method is undefined.")
  | _ => WriteLine("Else Exception")
} finally {
 ...
}
```

## throw
C\#と同じです．

```nemerle:throw
throw Exception();
```

## P/Invoke
C\#と全く同じなので気にすることはありません．

```nemerle:Pinvoke
[DllImport("msvcrt.dll")]
public extern static puts(c : string) : int;
```

## ラベル
存在しますが，ややこしいので今回は省きます．

# 〆
[入門Ⅵへ](http://qiita.com/Gnico/items/19ee4aebcda592947d01)