M.Hiroi's Home Page
http://www.geocities.jp/m_hiroi/

C# Programming

お気楽C#プログラミング超入門

[ Home | C# ]

C# の基礎知識

●基本的なデータ型

csharp> int[] a = new int[10]; 
csharp> a[0];
0
csharp> a[9] = 1;
csharp> a[9];
1
csharp> int[,] b = {{1,2,3},{4,5,6},{7,8,9}};
csharp> b[0,0];
1
csharp> b[2,2]; 
9
csharp> b[2,2] = 10;
csharp> b[2,2];      
10
csharp> var c = new int[3, 4];
csharp> c.Length;
12
csharp> c.GetLength(0);
3
csharp> c.GetLength(1);
4

●基本的な演算子

●基本的な制御構造

●関数

リスト : 階乗とフィボナッチ関数

using System;

class Test {
  // 再帰
  static long Fact(long n) {
    return n == 0 ? 1 : n * Fact(n - 1);
  }

  // 繰り返し
  static long Facti(long n) {
    long a = 1;
    for (long i = 2; i <= n; i++) a *= i;
    return a;
  }

  // 再帰
  static int Fibo(int n) {
    if (n < 2) return n;
    return Fibo(n - 2) + Fibo(n - 1);
  }

  // 繰り返し
  static int Fiboi(int n) {
    int a = 0, b = 1;
    while (n-- > 0) {
      int c = a + b;
      a = b;
      b = c;
    }
    return a;
  }

  static void Main() {
    Console.WriteLine("{0}! = {1}", 10, Fact(10));
    Console.WriteLine("{0}! = {1}", 15, Fact(15));
    Console.WriteLine("{0}! = {1}", 20, Fact(20));
    Console.WriteLine("{0}! = {1}", 10, Facti(10));
    Console.WriteLine("{0}! = {1}", 15, Facti(15));
    Console.WriteLine("{0}! = {1}", 20, Facti(20));
    Console.WriteLine("Fibo({0}) = {1}", 10, Fibo(10));
    Console.WriteLine("Fibo({0}) = {1}", 15, Fibo(15));
    Console.WriteLine("Fibo({0}) = {1}", 20, Fibo(20));
    Console.WriteLine("Fiboi({0}) = {1}", 10, Fiboi(10));
    Console.WriteLine("Fiboi({0}) = {1}", 15, Fiboi(15));
    Console.WriteLine("Fiboi({0}) = {1}", 20, Fiboi(20));
  }
}
C>factfibo
10! = 3628800
15! = 1307674368000
20! = 2432902008176640000
10! = 3628800
15! = 1307674368000
20! = 2432902008176640000
Fibo(10) = 55
Fibo(15) = 610
Fibo(20) = 6765
Fiboi(10) = 55
Fiboi(15) = 610
Fiboi(20) = 6765

●変数

●クラス

リスト : 簡単な例題 (Point, Point3D クラス)

using System;

class Point {
  double x = 0.0, y = 0.0;

  // コンストラクタ
  public Point() { }
  public Point(double x, double y) {
    this.x = x;
    this.y = y;
  }

  // メソッド
  public double Distance(Point p) {
    double dx = x - p.x;
    double dy = y - p.y;
    return Math.Sqrt(dx * dx + dy * dy);
  }
}

class Point3D {
  double x = 0.0, y = 0.0, z = 0.0;

  // コンストラクタ
  public Point3D() { }
  public Point3D(double x, double y, double z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }

  // メソッド
  public double Distance(Point3D p) {
    double dx = x - p.x;
    double dy = y - p.y;
    double dz = z - p.z;
    return Math.Sqrt(dx * dx + dy * dy + dz * dz);
  }
}

class Test {
  static void Main() {
    var p1 = new Point();
    var p2 = new Point(1.0, 1.0);
    Console.WriteLine("{0}", p1.Distance(p2));
    var p3 = new Point3D();
    var p4 = new Point3D(1.0, 1.0, 1.0);
    Console.WriteLine("{0}", p3.Distance(p4));
  }
}
C>point
1.4142135623731
1.73205080756888

●継承

リスト : 継承の簡単なサンプル

using System;

class Foo {
  int x = 0, y = 0;

  public Foo() {}
  public Foo(int a, int b) {
    x = a;
    y = b;
  }

  // アクセスメソッド
  public int GetX() { return x; }
  public int GetY() { return y; }
  public void SetX(int a) { x = a; }
  public void SetY(int b) { y = b; }

  // 合計値を求める
  public int Sum() {
    return x + y;
  }
}

class Bar : Foo {
  int z = 0;

  public Bar() { }
  public Bar(int a, int b, int c) : base(a, b) {
    z = c;
  }

  // アクセスメソッド
  public int GetZ() { return z; }
  public void SetZ(int c) { z = c; }

  // 合計値を求める
  public new int Sum() {
    return z + base.Sum();
  }
}

class Test {
  static void Main() {
    var a = new Foo(1, 2);
    var b = new Bar(10, 20, 30);
    Console.WriteLine("{0}", a.Sum());  // 3 と表示
    Console.WriteLine("{0}", b.Sum());  // 60 と表示
  }
}
C>test
3
60

●仮想関数とポリモーフィズム

リスト : 仮想関数の簡単な例題

using System;

class Foo {
  int x = 0, y = 0;

  public Foo() {}
  public Foo(int a, int b) {
    x = a;
    y = b;
  }

  // アクセスメソッド
  public int GetX() { return x; }
  public int GetY() { return y; }
  public void SetX(int a) { x = a; }
  public void SetY(int b) { y = b; }

  // 合計値を求める
  public virtual int Sum() {
    return x + y;
  }
}

class Bar : Foo {
  int z = 0;

  public Bar() { }
  public Bar(int a, int b, int c) : base(a, b) {
    z = c;
  }

  // アクセスメソッド
  public int GetZ() { return z; }
  public void SetZ(int c) { z = c; }

  // 合計値を求める
  public override int Sum() {
    return z + base.Sum();
  }
}

class Test {
  static void Main() {
    Foo a = new Foo(1, 2);
    Foo b = new Bar(10, 20, 30);        // アップキャスト
    Console.WriteLine("{0}", a.Sum());  // 3 と表示
    Console.WriteLine("{0}", b.Sum());  // 60 と表示
  }
}

●抽象クラスと抽象メソッド

リスト : 抽象クラスと抽象メソッドの簡単な例題

using System;

abstract class Figure {
  public abstract string KindOf();
  public abstract double Area();
  public void Print(){
    Console.WriteLine("{0}: area = {1}", KindOf(), Area());
  }
}

// 三角形
class Triangle : Figure {
  double altitude, base_line;
  public Triangle(double a, double b){
    altitude = a;
    base_line = b;
  }
  public override string KindOf(){
    return "Triangle";
  }
  public override double Area(){
    return altitude * base_line / 2.0;
  }
}

// 四角形
class Rectangle : Figure {
  double width, height;
  public Rectangle(double w, double h){
    width = w;
    height = h;
  }
  public override string KindOf(){
    return "Rectangle";
  }
  public override double Area(){
    return width * height;
  }
}

// 円
class Circle : Figure {
  double radius;
  public Circle(double r){
    radius = r;
  }
  public override string KindOf(){
    return "Circle";
  }
  public override double Area(){
    return radius * radius * Math.PI;
  }
}

class Test {
  static void Main() {
    Triangle a = new Triangle(2.0, 2.0);
    Rectangle b = new Rectangle(2.0, 2.0);
    Circle c = new Circle(2.0);
    a.Print();
    b.Print();
    c.Print();
    Figure[] figTable = {
      new Triangle(3.0, 3.0),
      new Rectangle(3.0, 3.0),
      new Circle(3.0),
    };
    foreach(Figure f in figTable) {
      f.Print();
    }
  }
}
C>figure
Triangle: area = 2
Rectangle: area = 4
Circle: area = 12.5663706143592
Triangle: area = 4.5
Rectangle: area = 9
Circle: area = 28.2743338823081

●インターフェース

リスト : インターフェースの簡単な使用例

using System;

// インターフェースの定義
interface Figure {
  string KindOf();
  double Area();
  void Print();
}

// 三角形
class Triangle : Figure {
  double altitude, base_line;
  public Triangle(double a, double b){
    altitude = a;
    base_line = b;
  }
  public string KindOf(){
    return "Triangle";
  }
  public double Area(){
    return altitude * base_line / 2.0;
  }
  public void Print(){
    Console.WriteLine("{0}: area = {1}", KindOf(), Area());
  }
}

// 四角形
class Rectangle : Figure {
  double width, height;
  public Rectangle(double w, double h){
    width = w;
    height = h;
  }
  public string KindOf(){
    return "Rectangle";
  }
  public double Area(){
    return width * height;
  }
  public void Print(){
    Console.WriteLine("{0}: area = {1}", KindOf(), Area());
  }
}

// 円
class Circle : Figure {
  double radius;
  public Circle(double r){
    radius = r;
  }
  public string KindOf(){
    return "Circle";
  }
  public double Area(){
    return radius * radius * Math.PI;
  }
  public void Print(){
    Console.WriteLine("{0}: area = {1}", KindOf(), Area());
  }
}

class Test {
  static void Main() {
    Triangle a = new Triangle(2.0, 2.0);
    Rectangle b = new Rectangle(2.0, 2.0);
    Circle c = new Circle(2.0);
    a.Print();
    b.Print();
    c.Print();
    Figure[] figTable = {
      new Triangle(3.0, 3.0),
      new Rectangle(3.0, 3.0),
      new Circle(3.0),
    };
    foreach(Figure f in figTable) {
      f.Print();
    }
  }
}

●プロパティ

リスト : プロパティの簡単な例題

using System;

class Foo {
  public int X { set; get; }
  public int Y { set; get; }

  // 合計値を求める
  public int Sum {
    get { return X + Y; }
  }
}

class Test {
  static void Main() {
    var a = new Foo();
    a.X = 10;
    a.Y = 20;
    Console.WriteLine("{0}", a.Sum);  // 30
  }
}
リスト : getter だけ自動生成する

using System;

class Foo {
  public Foo(int a, int b) {
    X = a;
    Y = b;
  }

  public int X { get; }
  public int Y { get; }

  // 合計値を求める
  public int Sum {
    get { return X + Y; }
  }
}

class Test {
  static void Main() {
    var a = new Foo(10, 20);
    Console.WriteLine("{0}", a.Sum);  // 30
  }
}

●ジェネリック

リスト : ジェネリッククラスの簡単な使用例

using System;

class Foo<T> {
  T x;
  public Foo() { x = default(T); }
  public Foo(T n) { x = n; }
  public T Get() { return x; }
};

class Bar<T> where T : new() {
  T y;
  public Bar() { y = new T(); }
  public Bar(T n) { y = n; }
  public T Get() { return y; }
};

class Baz {
  int z;
  public Baz() { z = 123; }
  public Baz(int n) { z = n; }
  public int Get() { return z; }
};

class Test {
  static void Main() {
    var a = new Foo<int>();
    var b = new Foo<double>(1.2345);
    var c = new Bar<Baz>();
    Console.WriteLine("{0}", a.Get());         // 0
    Console.WriteLine("{0}", b.Get());         // 1.2345
    Console.WriteLine("{0}", c.Get().Get());   // 123
  }
}
リスト : ジェネリックメソッドの簡単な使用例

using System;

class Test {
  // 型変数の場合、比較演算子は使えないので、
  // インターフェース IComparable を使う
  static int IndexOf<T>(T[] buff, T x) where T : IComparable {
    for (int i = 0; i < buff.Length; i++) {
      if (x.CompareTo(buff[i]) == 0) return i;
    }
    return -1;
  }

  static void Main() {
    int[] a = {1,2,3,4,5,6,7,8};
    double[] b = {1.1, 2.2, 3.3, 4.4, 5.5};
    Console.WriteLine("{0}", IndexOf(a, 5));   // 4
    Console.WriteLine("{0}", IndexOf(a, 9));   // -1
    Console.WriteLine("{0}", IndexOf(b, 4.4)); // 3
    Console.WriteLine("{0}", IndexOf(b, 5.0)); // -1
  }
}

●構造体

リスト : 構造体の簡単な使用例

using System;

struct Point {
  double x, y;
  public Point(double a, double b) {
    x = a;
    y = b;
  }
  public double Distance(Point p) {
    double dx = x - p.x;
    double dy = y - p.y;
    return Math.Sqrt(dx * dx + dy * dy);
  }
}

class Test {
  static void Main() {
    Point p1 = new Point();
    Point p2 = new Point(1.0, 1.0);
    Console.WriteLine("{0}", p1.Distance(p2));  // 1.4142135623731
  }
}
リスト : 構造体とジェネリックの簡単な使用例

using System;

struct Pair<T, U> {
  T p;
  U q;
  public Pair(T a, U b) {
    p = a;
    q = b;
  }
  public T Fst() { return p; }
  public U Snd() { return q; }
};

class Test {
  static void Main() {
    var a = new Pair<string, int>("foo", 10);
    var b = new Pair<string, double>("bar", 1.2345);
    Console.WriteLine("{0}, {1}", a.Fst(), a.Snd());    // foo, 10
    Console.WriteLine("{0}, {1}", b.Fst(), b.Snd());    // bar, 1.2345
  }
}

●デリゲートとラムダ式

リスト : デリゲートの簡単な使用例

using System;

class Test {
  // int を受け取って int を返すメソッドの型 IntFunc を定義
  delegate int IntFunc(int x);

  // マッピング (intFunc 型のメソッドを受け取る高階関数)
  static int[] Map(IntFunc func, int[] xs) {
    int[] ys = new int[xs.Length];
    for (int i = 0; i < xs.Length; i++)
      ys[i] = func(xs[i]);
    return ys;
  }

  // 引数を二乗するメソッド
  static int Square(int x) { return x * x; }
  
  static void Main() {
    int[] a = {1, 2, 3, 4, 5};
    foreach(int x in Map(Square, a))
      Console.Write("{0} ", x);        // 1 4 9 16 25 
    Console.WriteLine("");
  }
}
リスト : ラムダ式の簡単な使用例

using System;

class Test {
  // 配列のマッピング
  static T[] Map<T>(Func<T, T> func, T[] xs) {
    T[] ys = new T[xs.Length];
    for (int i = 0; i < xs.Length; i++)
      ys[i] = func(xs[i]);
    return ys;
  }

  static void Main() {
    int[] a = {1, 2, 3, 4, 5};
    double[] b = {1.1, 2.2, 3.3, 4.4, 5.5};
    foreach(int x in Map(n => n * n, a))
      Console.Write("{0} ", x);              // 1 4 9 16 25
    Console.WriteLine("");
    foreach(double x in Map(n => n * n, b))
      Console.Write("{0} ", x);              // 1.21 4.84 10.89 19.36 30.25
    Console.WriteLine("");
  }
}
csharp> Func<int, Func<int, int>> make_adder = n => x => n + x;
csharp> Func<int, int> add10 = make_adder(10);
csharp> add10(1);
11
csharp> add10(20);
30
csharp> Action<string> greeting = mes => Console.WriteLine("hello, {0}", mes);
csharp> greeting("M.Hiroi");
hello, M.Hiroi
csharp> greeting += mes => Console.WriteLine("good by, {0}", mes);
csharp> greeting("M.Hiroi");
hello, M.Hiroi
good by, M.Hiroi

●例外処理

try {

  ...

} catch(例外クラス [引数]) {

  ...

} finally {

  ...

}
csharp> class Foo : Exception {};
csharp> try { throw new Foo(); } catch(Foo) { Console.WriteLine("catch Foo"); };
catch Foo
csharp> try { Console.WriteLine("foo"); } finally { Console.WriteLine("oops!");
foo
oops!
csharp> try { throw new Foo(); } catch(Foo) { Console.WriteLine("catch Foo"); } finally { Console.WriteLine("oops!"); };
catch Foo
oops!

●可変長配列

csharp> var a = new List<int>();
csharp> for (int i = 0; i < 10; i++) a.Add(i);
csharp> a
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
csharp> a.Insert(0, -1);
csharp> a
{ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
csharp> a.RemoveAt(0);
csharp> a
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
csharp> a.Count;
10
csharp> a.Capacity;
16
csharp> a.RemoveAt(a.Count - 1);
csharp> a
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 }

●連想配列 (ハッシュ)

csharp> var a = new Dictionary();
csharp> a["foo"] = 10;
csharp> a["baz"] = 20;
csharp> a["bar"] = 30;
csharp> a["oops"] = 40;
csharp> a;
{{ "foo", 10 }, { "baz", 20 }, { "bar", 30 }, { "oops", 40 }}
csharp> a.ContainsKey("foo");
true
csharp> a.ContainsKey("Foo");
false
csharp> a.Keys;
{ "foo", "baz", "bar", "oops" }
csharp> a.Remove("foo");
true
csharp> a;
{{ "baz", 20 }, { "bar", 30 }, { "oops", 40 }}
csharp> a.Remove("foo");
false
csharp> a.Remove("Foo");
false

●イテレータ

リスト : イテレータの簡単な例題

using System;
using System.Collections;

class Foo : IEnumerable {
  int a, b, c;
  public Foo(int x, int y, int z) {
    a = x;
    b = y;
    c = z;
  }

  public IEnumerator GetEnumerator() {
    yield return a;
    yield return b;
    yield return c;
  }
}

class Test {
  static void Main() {
    var a = new Foo(1, 2, 3);
    foreach(int n in a) {
      Console.WriteLine("{0}", n);
    }
  }
}
C>test
1
2
3
リスト : ジェネリック版

using System;
using System.Collections;
using System.Collections.Generic;

class Foo<T> : IEnumerable<T> {
  T a, b, c;
  public Foo(T x, T y, T z) {
    a = x;
    b = y;
    c = z;
  }

  public IEnumerator<T> GetEnumerator() {
    yield return a;
    yield return b;
    yield return c;
  }

  // public は付けない
  IEnumerator IEnumerable.GetEnumerator() {
    return this.GetEnumerator();
  }
}

class Test {
  static void Main() {
    var a = new Foo<int>(1, 2, 3);
    foreach(int n in a) {
      Console.WriteLine("{0}", n);
    }
  }
}
C>test
1
2
3

●インデクサー

リスト : インデクサーの簡単な例題

using System;

class Foo {
  int a, b, c;
  public Foo(int x, int y, int z) {
    a = x;
    b = y;
    c = z;
  }

  public int this[int n] {
    set {
      switch(n) {
      case 0: a = value; break;
      case 1: b = value; break;
      default: c = value; break;
      }
    }
    get {
      switch(n) {
      case 0: return a;
      case 1: return b;
      default: return c;
      }
    }
  }
}

class Test {
  static void Main() {
    var a = new Foo(1, 2, 3);
    for (int i = 0; i < 3; i++) {
      a[i] *= 10;
      Console.WriteLine("{0}", a[i]);
    }
  }
}
C>test
10
20
30

●LINQ

csharp> var a = new int[8] {1,2,3,4,5,6,7,8};

csharp> a.Select(n => n * n);
{ 1, 4, 9, 16, 25, 36, 49, 64 }
csharp> a.Select(n => n * 1.5);
{ 1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12 }

csharp> a.Where(n => n % 2 == 0);
{ 2, 4, 6, 8 }
csharp> a.Where(n => n % 2 != 0);
{ 1, 3, 5, 7 }

csharp> a.Aggregate((sum, n) => sum + n);
36
csharp> a.Aggregate(100, (sum, n) => sum + n);
136

csharp> var b = new int[] {5,6,4,7,3,8,2,9,1,0};
csharp> b.OrderBy(n => n);
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
csharp> b.OrderByDescending(n => n);
{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }

csharp> b.First(n => n % 2 == 0);
6
csharp> b.Last(n => n % 2 != 0);
1

csharp> var c = new int[] {2,4,6,8,10};
csharp> c.All(n => n % 2 == 0);
true
csharp> c.Any(n => n % 2 != 0);
false

csharp> var d = new [] { new {name="foo", gr=1}, new {name="bar", gr=2},
      > new {name="baz", gr=1}, new {name="oops", gr=2}};
csharp> d
{ { name = foo, gr = 1 }, { name = bar, gr = 2 }, { name = baz, gr = 1 }, { name = oops, gr = 2 } }
csharp> d.GroupBy(n => n.gr)s), 0 warnings
{ { { name = foo, gr = 1 }, { name = baz, gr = 1 } }, { { name = bar, gr = 2 }, { name = oops, gr = 2 } } }

●LINQ (クエリ式)

csharp> var b = new int[] {5,6,4,7,3,8,2,9,1,0};
csharp> from x in b where x % 2 == 0 select x;
{ 6, 4, 8, 2, 0 }
csharp> from x in b where x % 2 == 0 orderby x select x;
{ 0, 2, 4, 6, 8 }
csharp> var xs = new[] { new {name="foo", score=10}, new {name="bar", score=20}, new {name="baz", score=40}, new {name="oops", score=30}};
csharp> from x in xs where x.score > 20 select x.name;
{ "baz", "oops" }
csharp> from x in xs where x.score > 20 select x;
{ { name = baz, score = 40 }, { name = oops, score = 30 } }
リスト : クエリ式の簡単な使用例

using System;
using System.Linq;

class Test {
  static void Main() {
    var heightTable = new [] {
      new {id=1,  name="Ada",    height=148.7, rank=1},
      new {id=2,  name="Alice",  height=149.5, rank=2},
      new {id=3,  name="Carey",  height=133.7, rank=3},
      new {id=4,  name="Ellen",  height=157.9, rank=4},
      new {id=5,  name="Hanna",  height=154.2, rank=1},
      new {id=6,  name="Janet",  height=147.8, rank=2},
      new {id=7,  name="Linda",  height=154.6, rank=3},
      new {id=8,  name="Maria",  height=159.1, rank=4},
      new {id=9,  name="Miranda",height=148.2, rank=1},
      new {id=10, name="Sara",   height=153.1, rank=2},
      new {id=11, name="Tracy",  height=138.2, rank=3},
      new {id=12, name="Violet", height=138.7, rank=4},
    };
    var xs = from x in heightTable where x.height < 140
             orderby x.height select new {x.name, x.height};
    foreach(var x in xs) {
      Console.WriteLine("{0}, {1}", x.name, x.height);
    }
    var ys = from x in heightTable where x.height > 150
             orderby x.height descending select new {x.name, x.height};
    foreach(var y in ys) {
      Console.WriteLine("{0}, {1}", y.name, y.height);
    }
    var gs = from x in heightTable
      group new { x.name, x.height } by x.rank;
    foreach(var g in gs) {
      Console.Write("{0}: ", g.Key);  // プロパティ Key でキーの値を取得できる
      foreach(var p in g) {
        Console.Write("({0}, {1}) ", p.name, p.height);
      }
      Console.WriteLine("");
    }
  }
}
C>test
Carey, 133.7
Tracy, 138.2
Violet, 138.7
Maria, 159.1
Ellen, 157.9
Linda, 154.6
Hanna, 154.2
Sara, 153.1
1: (Ada, 148.7) (Hanna, 154.2) (Miranda, 148.2)
2: (Alice, 149.5) (Janet, 147.8) (Sara, 153.1)
3: (Carey, 133.7) (Linda, 154.6) (Tracy, 138.2)
4: (Ellen, 157.9) (Maria, 159.1) (Violet, 138.7)

●ファイル入出力

リスト : テキストファイルの連結 (cat.cs)

using System;
using System.IO;

class Test {
  static void Main(string[] args) {
    foreach(string name in args) {
      using (var s = new StreamReader(name)) {
        string buff;
        while ((buff = s.ReadLine()) != null) {
          Console.WriteLine(buff);
        }
      }
    }
  }
}
リスト : テキストファイルのコピー (cp.cs)

using System;
using System.IO;

class Test {
  static void Main(string[] args) {
    if (args.Length < 2) {
      Console.WriteLine("arguments error");
    } else {
      using (var sIn = new StreamReader(args[0])) {
        using (var sOut = new StreamWriter(args[1])) {
          string buff;
          while ((buff = sIn.ReadLine()) != null) {
            sOut.WriteLine(buff);
          }
        }
      }
    }
  }
}

●名前空間

csharp> namespace Foo {
      > namespace Bar {
      > class Baz {}
      > }
      > class Oops {}
      > }
csharp> new Foo.Bar.Baz();
Foo.Bar.Baz
csharp> new Foo.Oops()
Foo.Oops
csharp> using Foo;
csharp> using Foo.Bar;
csharp> new Baz();
Foo.Bar.Baz
csharp> new Oops();
Foo.Oops

●ライブラリの作成

リスト : hello.cs

using System;

namespace HelloWorld {
  public class Hello {
    public static void Greeting() {
      Console.WriteLine("Hello World");
    }
  }
}
C>mcs -t:library -out:hello.dll hello.cs
リスト : hellotest.cs

using HelloWorld;

class Test {
  static void Main() {
    Hello.Greeting();
  }
}
C>mcs -r:hello.dll hellotest.cs

C>hellotest
Hello World

●値呼びと参照呼び

リスト : 値の交換

using System;

class Test {
  static void Swap(ref int a, ref int b) {
    int c = a;
    a = b;
    b = c;
  }

  static void Main() {
    int a = 1, b = 2;
    Console.WriteLine("a = {0}, b = {1}", a, b);
    Swap(ref a, ref b);
    Console.WriteLine("a = {0}, b = {1}", a, b);
  }
}
C>test
a = 1, b = 2
a = 2, b = 1
リスト : out の使い方

using System;

class Test {
  // 商と剰余を返す (Math.DivRem() と同じ)
  static int DivRem(int x, int y, out int z) {
    z = x % y;
    return x / y;
  }

  static void Main() {
    int r;  // 初期化しなくてもよい
    int q = DivRem(11, 4, out r);
    Console.WriteLine("{0}, {1}", q, r);
  }
}
C>test
2, 3

●データ型の判定

csharp> class Foo {};
csharp> class Bar : Foo {};
csharp> class Baz : Bar {};
csharp> Foo a = new Foo();
csharp> Foo b = new Bar();
csharp> Foo c = new Baz();
csharp> a is Foo;
true
csharp> a is Bar;
false
csharp> b is Foo;
true
csharp> b is Bar;
true
csharp> b is Baz;
false
csharp> c is Foo;
true
csharp> c is Bar;
true
csharp> c is Baz;
true
csharp> a as Foo;
Foo
csharp> a as Bar;
null
csharp> b as Bar;
Bar
csharp> b as Baz;
null
csharp> c as Baz;
Baz
csharp> typeof(Foo).Name;
"Foo"
csharp> b.GetType();
Bar
csharp> b.GetType().Name;
"Bar"
csharp> c.GetType().Name;
"Baz"

●演算子の多重定義

//
// ratio.cs : 有理数
//
//            Copyright (C) 2016 Makoto Hiroi
//
using System;
using System.Numerics;

struct Ratio : IComparable {
  public BigInteger Numer { get; }  // 分子
  public BigInteger Denom { get; }  // 分母

  public Ratio(BigInteger p, BigInteger q) {
    BigInteger a = BigInteger.GreatestCommonDivisor(p, q);
    Numer = p / a;
    Denom = q / a;
    if (Denom < 0) {
      Numer = - Numer;
      Denom = - Denom;
    }
  }

  public static Ratio operator +(Ratio a, Ratio b) {
    return new Ratio(a.Numer * b.Denom + b.Numer * a.Denom, a.Denom * b.Denom);
  }

  public static Ratio operator -(Ratio a, Ratio b) {
    return new Ratio(a.Numer * b.Denom - b.Numer * a.Denom, a.Denom * b.Denom);
  }

  public static Ratio operator *(Ratio a, Ratio b) {
    return new Ratio(a.Numer * b.Numer, a.Denom * b.Denom);
  }

  public static Ratio operator /(Ratio a, Ratio b) {
    return new Ratio(a.Numer * b.Denom, a.Denom * b.Numer);
  }
  
  // IComparable 用のメソッド
  public int CompareTo(Object obj) {
    if (!(obj is Ratio)) return 1;
    Ratio r = (Ratio)obj;
    BigInteger a = Numer * r.Denom;
    BigInteger b = r.Numer * Denom;
    if (a == b) return 0;
    else if (a < b) return -1;
    else return 1;
  }

  public override bool Equals(object obj) {
    if (!(obj is Ratio)) return false;
    Ratio r = (Ratio)obj;
    return Numer == r.Numer && Denom == r.Denom;
  }

  // とても適当なので実際に使ってはいけない
  public override int GetHashCode() {
    return ((Numer << 7) ^ Denom).GetHashCode();
  }

  public static bool operator ==(Ratio a, Ratio b) {
    return a.Equals(b);
  }
  public static bool operator !=(Ratio a, Ratio b) {
    return !a.Equals(b);
  }
  public static bool operator <(Ratio a, Ratio b) {
    return a.CompareTo(b) < 0;
  }
  public static bool operator <=(Ratio a, Ratio b) {
    return a.CompareTo(b) <= 0;
  }
  public static bool operator >(Ratio a, Ratio b) {
    return a.CompareTo(b) > 0;
  }
  public static bool operator >=(Ratio a, Ratio b) {
    return a.CompareTo(b) >= 0;
  }

  // 表示
  public override string ToString() {
    return Numer.ToString() + "/" + Denom.ToString();
  }
}

class Test {
  static void Main() {
    Ratio a = new Ratio(1, 2);
    Ratio b = new Ratio(1, 3);
    Ratio c = new Ratio(1, 4);

    Console.WriteLine(a);
    Console.WriteLine(b);
    Console.WriteLine(c);
    Console.WriteLine(a + b);
    Console.WriteLine(a - b);
    Console.WriteLine(a * b);
    Console.WriteLine(a / b);
    Console.WriteLine(c + b);
    Console.WriteLine(c - b);
    Console.WriteLine(c * b);
    Console.WriteLine(c / b);
    Console.WriteLine(a == c + c);
    Console.WriteLine(a != c + c);
    Console.WriteLine(a < b);
    Console.WriteLine(a > b);
    Console.WriteLine(a <= b);
    Console.WriteLine(a >= b);
    Console.WriteLine(b < c);
    Console.WriteLine(b > c);
    Console.WriteLine(b <= c);
    Console.WriteLine(b >= c);

    var buff = new Ratio[] {b, a, c};
    Array.Sort(buff);
    foreach(Ratio x in buff) {
      Console.Write("{0} ", x);
    }
    Console.WriteLine("");
  }
}
C>ratio
1/2
1/3
1/4
5/6
1/6
1/6
3/2
7/12
-1/12
1/12
3/4
True
False
False
True
False
True
False
True
False
True
1/4 1/3 1/2

●null 許容型

csharp> int? a = 10;
csharp> int? b = null;
csharp> a
10
csharp> b
null
csharp> int c = a ?? -1;
csharp> c
10
csharp> int d = b ?? -1;
csharp> d
-1
csharp> a + a;
20
csharp> a + b;
null

●日付と時刻

csharp> var a = new DateTime(2016, 1, 1);
csharp> var b = new DateTime(2016, 11, 6);
csharp> a
01/01/2016 00:00:00
csharp> b
11/06/2016 00:00:00
csharp> var c = b - a;
csharp> c;
310.00:00:00
csharp> c.TotalDays;
310
csharp> c.TotalHours;
7440
csharp> c.TotalSeconds;
26784000
リスト : 簡単な実行時間の計測

using System;

class Test {
  // 二重再帰
  static long Fibo(long n) {
    if (n < 2) return n;
    return Fibo(n - 2) + Fibo(n - 1);
  }

  static void Main() {
    var s = DateTime.Now;
    Console.WriteLine(Fibo(42));
    Console.WriteLine((DateTime.Now - s).TotalSeconds);
  }
}
C>test
267914296
3.7542147

●書式指定文字列

csharp> 255.ToString("d");
"255"
csharp> 255.ToString("x");
"ff"
csharp> 255.ToString("X");
"FF"
csharp> x.ToString("f");
"1.23"
csharp> double x = 1.23456789;
csharp> x.ToString("e");
"1.234568e+000"
csharp> x.ToString("g");
"1.23456789"
csharp> 123456789.ToString("n");
"123,456,789.00"
csharp> a
11/06/2016 12:34:56
csharp> a.ToString("d");
"11/06/2016"
csharp> a.ToString("D");
"Sunday, 06 November 2016"
csharp> a.ToString("t");
"12:34"
csharp> a.ToString("T");
"12:34:56"
csharp> a.ToString("f");
"Sunday, 06 November 2016 12:34"
csharp> a.ToString("F");
"Sunday, 06 November 2016 12:34:56"
csharp> a.ToString("g");
"11/06/2016 12:34"
csharp> a.ToString("G");
"11/06/2016 12:34:56"
csharp> Console.WriteLine("[{0,8}]", "hello");
[   hello]
csharp> Console.WriteLine("[{0,-8}]", "hello");
[hello   ]
csharp> Console.WriteLine("[{0,-8:d}]", 123);
[123     ]
csharp> Console.WriteLine("[{0,8:d}]", 1234);
[    1234]
csharp> Console.WriteLine("[{0,-8:d}]", 1234);
[1234    ]
csharp> Console.WriteLine("[{0:d8}]", 1234);
[00001234]
csharp> Console.WriteLine("{0:f}", 1.2345678);
1.23
csharp> Console.WriteLine("{0:f7}", 1.2345678);
1.2345678
csharp> Console.WriteLine("{0:###.###}", 123.45);
123.45
csharp> Console.WriteLine("{0:###.000}", 123.45);
123.450
csharp> Console.WriteLine("{0:0000.000}", 123.45);
0123.450

Copyright (C) 2016 Makoto Hiroi
All rights reserved.

[ Home | C# ]