Javaプログラマが初めてC#(C++++)を書いた時に面食らったこと。言語仕様の差異まとめ

簡単に画面（Form）アプリケーションを作成できる！
その画面、Windowsユーザーならすぐ起動できる！
そんなC#を学ぼうと思って、javaプログラマが始めてC#を初めてプログラミングして気になったことをまとめました。
文字が多いと見る気が失せるので、なるべくコードで書いています


▼コンソールアウト
----------------------------------------------------
```java:java
public class Foo {
	public static void main(String[] args) {
		int foo = 10;
		System.out.println("Hello,java World!");
		System.out.println("foo=" + foo);
		System.out.printf("foo=%s", foo);	
	}
}
```
```C#:C#
using System;
public class Foo{
	public static void Main(){
		int foo = 10;
		Console.WriteLine("Hello,CSharp World!");
		Console.WriteLine("foo=" + foo);
		Console.WriteLine("foo={0}", foo);
	}
}
```

▼構造化プログラミング３大要素の記法(順次・反復・分岐)は同じ
----------------------------------------------------
下記の基本的なプログラミング記法は概ね同じ
* インクリメント、デクリメント
* if
* for
* switch

▼データ型の比較（is演算子）
-----------------------------------------------------

```C#:C#
if("hoge" is string){
	Console.WriteLine("型はstringです");
}else{
	Console.WriteLine("型はstringではありません");
}
```

▼ForEachの記法差異
----------------------------------------------------

```java:java
	String[10] fooList = new String[10];
	for(String foo : fooList){
		System.out.println(foo);
	
}
```
```C#:C#
	string[] strs = {"hoge", "fuga", "piyo"};
	foreach(string str in strs){
		Console.WriteLine(str);
	
}
```
▼デストラクタ(javaだとfinalize)の記法
----------------------------------------------------
C言語やC++言語では個別に定義する必要があるガベージコレクションをjavaはもちろん、C#も変数のスコープから解析して自動的に実施してくれる
（※ガベージコレクションとは、不要になったオブジェクトのメモリ領域を解放すること）

```java:javaはfinalize
public class Foo extends Object {
	@Override
	protected
	void finalize() {
		// GC時の処理を記載する	
	}
}
```
```C#:C#のfinalizeはチルダで記載
class Foo{
	~Foo()	{
		// GC時の処理を記載する	
	}
}
```

▼メソッド引数の参照・値渡し（refとout）※VBAでいうByRefとByVAL
--------------------------------------------------------
javaでいう、プリミティブ型をメソッド引数渡ししたときには、必ず値渡しとなり、引数にうけとった値をメソッド内部で書き換えても呼び出し元の変数値に影響を与えない。
C#では、ExcelVBA(のFunction)などと同様にメソッド引数をメソッド内部で値を変更させ、それを引数元の変数にまで影響を与えることができる。

```C#:C#
public class Foo{
	public void exchange(int a,int b){
		int temp;
		temp = a;
		a = b;
		b = temp;
	}
	public void Foo(){
		int x = 10;
		int y = 20;
		exchange(x,y); // 値渡し
		exchange(out x,out y);	// 参照渡し
		exchange(ref x,ref y);
	}
}
```

▼インデクサ
-----------------------------------------
クラスインスタンスを配列のプロパティ値のように利用することができるC#独特な言語仕様。C#に用意されているdictionary（※javaだとMap）がこの記法にあたるためjavaプログラマーも特性を覚えることが必須。

```C#:C#基本プログラムの例
using System;
class Boo{
	string[] strs = new string[5];
	//インデクサ -> this[indexの型　index]
	public string this[int i]					
	{
		get{
			return strs[i];
		}
		set{
			strs[i] = value;
		}	
	}
}
class Foo{
	public static void Main()
	{
		Boo boo = new Boo();
		// ↓自動的にsetterが呼ばれる
		boo[0] = "hoge";
		// ↓自動的にgetterが呼ばれる
		Console.WriteLine(boo[0]);
	}
}
```

▼C#のクラス・インタフェース継承
--------------------------------------------------
```java:java
class Boo extends Foo
```

```C#:C#だと継承の定義の書き方がコロン※javaと意味合いや定義は同じ
class Boo : Foo
```

C#のオーバーライド
------------------------------------------------
シグネチャが違ければ、同一メソッドも定義(オーバーロード)可能
javaとC#のオーバーライドの一番の違いは、C#はjavaと異なり"アノテーション"を介さない。
したがって、オーバーライドをしているメソッドかどうかを明示的に示す必要がある。
javaでは一律オーバーライドと読んでいるタイプが、C#では大きく３種類存在する

1.親クラスのメソッド子クラスで定義
(名前の隠蔽：C#ではオーバーロードと言わない)

```C#:C#親クラス
public void Method(){
	Console.WriteLine("hoge");
}
```
```C#:C#子クラス
new public void Method(){
	Console.WriteLine("fuga");
}
```

2.親クラスの仮想化メソッドを子クラスで定義
（仮想化メソッドはjavaの抽象メソッドとは違って、処理が記載できる）

```C#:C#親クラス
public virtual void Method(){
Console.WriteLine("hoge");
}
```

```C#:C#子クラス
public override void Method(){
Console.WriteLine("fuga");
}
```

3.抽象クラスの抽象メソッドを子クラスで定義（javaと同じオーバーライド）

```C#:C#親クラス
public abstract void Method();
```

```C#:C#子クラス
public override void Method(){
Console.WriteLine("fuga");
}
```

▼クラスファイルの分割定義
-----------------------------------------------------
javaにはない機能。クラスを2ファイルにわけて記載ができる。
その際には、クラスにpartial属性をつければ定義完了。
個人的にはイラナイ機能。スコープがわかりづらくてしようがない。

▼構造体(structure)
-----------------------------------------------------
javaにはない機能。構造体とは、クラス非常に似ている。
決定的に違うのは、クラスは参照型だが、構造体は値型のデータであること。
また、クラスと異なり継承はできない。
ストラクチャは、クラスの定義にstruct属性をつければ定義完了。
javaで一般的にいうエンティティとしての利用が期待できると思う。※詳細は割愛

▼デリゲート(delegate)
----------------------------------------------------
CやC++でいう関数へのポインタ。
メソッドへの参照を保存して、その参照をメソッドとして呼び出すことが可能
(シグネチャは一致している必要がある)複数定義も可能（※マルチキャストデリゲーション）
デリゲートは以下のようにメソッドの前にdelegate とつけることで定義完了

```C#:C#
	delegate public Object MethodName(Object objectName);
```