私がJavaよりC#をおすすめする理由
私は10年間Javaを使った後、PHP、Ruby、Node.js等の動的型言語を使いました。動的型言語の簡潔さに魅了され大ファンになりました。
その結果、Javaをディスるようになってしまったのですが(笑)、動的型言語にも不満がないわけではありません。
IDEによる入力補完やシンボルの検索機能などは静的型言語の方が手厚いですし、静的型言語であればコンパイル時に発見されるようなコーディングミスが動的型言語では実行しないと見つからないというデメリットもあります。
なので、
「静的型言語で動的型言語みたく簡潔に書ける言語があればいいのになぁ…」
と思っていたら、 そんな言語があったんです。
C#です!
「えっ? C#ってJavaをマネしただけでしょ?」って?そんなことありません。
C#は静的型言語の良さを持ちながら動的型言語のような簡潔さを持つ素晴らしい言語なんです。その魅力の一端を紹介します。
Contents
Javaのアクセサ地獄を解決するC#のプロパティ
Javaにはフィールド(インスタンス変数)をクラス外から設定参照するアクセサメソッドという概念があります。 get~、set~というお決まりのコードです。
public class UserInfo { private String email; private String password; public void getEmail() { return email; } public void setEmail(String s) { email = s; } public void getPassword() { return password; } public void setPassword(String s) { password = s; } } //使用例 UserInfo user = new UserInfo(); user.setEmail("[email protected]"); String email = user.getEmail();
「だったらフィールドをpublicにすりゃいいじゃん」とおもうのですが、Javaの設計慣習では「publicにしてしまうと、後でそのフィールドにアクセス制限をかけることができないのでアクセサメソッド経由でフィールドにアクセスする設計がよい」とされています。
例えば、後になってpasswordに値をセットするロジックに文字列長が8未満だったらエラーにしたいとなった場合に以下のように対処できるという発想です。
public void setPassword(String s) { if (s.length < 8) throw new PasswordSetException(s); password = s; }
まぁ、滅多にこんなことをすることはないでしょうけど、確かにアクセサメソッドを挟んでおくことで値の参照設定にロジックをはさむ柔軟性が生まれます。
ですが、そのためにいちいちアクセサメソッドを書くのは面倒です。
IDEによるアクセサコードの自動生成ができるので書く手間はある程度減らせますが、コードが冗長になる問題は残ります。 C#にはこれを解決するプロパティという機能があります。
public class UserInfo { private String email; private String password; public String Email { get { return email;} set { email = value }} public String Password { get { return password;} set { password = value }} } //使用例 UserInfo user = new UserInfo(); user.Email = "[email protected]"; String email = user.Email;
さらに短い書き方もできます。
public class UserInfo { public String Email { get; set;} public String Password { get; set; } }
プロパティが良いのはpublicフィールドの参照とプロパティ参照の記法が同じなので初めpublicフィールドで定義しておいて後で必要になったらプロパティに変えることができます。
publicフィールドからプロパティに変更しても呼び出し側の記法は同じなので変更する必要はありません。
public class UserInfo { public String email; public String password; } //使用例 UserInfo user = new UserInfo(); user.email = "[email protected]"; String email = user.email; //後で変更 public class UserInfo { //プロパティは頭が大文字じゃなくてもいい、大文字にしてるのはただの慣例 public String email { get; set;} public String password { get { return password;} set { if (value.length < 8) throw new PasswordSetException(value); password = value; } } } } //使用例(publicフィールドの時と同じ記法が使える) UserInfo user = new UserInfo(); user.email = "[email protected]"; String email = user.email;
JavaのHashMapを連想配列のような記法で扱えるC#のDictionary
JavaのHashMapはデータの追加、取得をメソッドで行いますが、C#のDictionaryはLL言語が連想配列を扱うような記法で追加、取得ができます。
・JavaのHashMapコード
HashMap<String, String> map = new HashMap<String, String>(); map.put("[email protected]", "pass1"); map.put("[email protected]", "pass2"); String password = map.get("[email protected]");
・C#のDictionaryコード
// C#はvarキーワードによる型推論ができるので型を省略できるのもナイス! var map = new Dictionary<String, String>(); map["[email protected]"] = "pass1"; map["[email protected]"] = "pass2"; String password = map["[email protected]"];
断然C#の方がすっきりしているし直観的にわかりやすいですね!
JavaのListを配列のような記法で扱えるC#のインデクサ
Javaには可変長配列を実装したArrayListというクラスがあります。これまたデータの追加、取得をメソッドで行います
ArrayList list = new ArrayList(); list.add("[email protected]"); list.add("[email protected]"); list.get(0); //[email protected]が返る list.get(1); //[email protected]が返る
C#にはインデクサという配列の記法を使ったアクセス方法があります。
var list = new List(); list.Add("[email protected]"); list.Add("[email protected]"); // 配列と同じ記法で参照できる(インデクサ) list[0]; //[email protected]が返る list[1]; //[email protected]が返る
C#だとRubyやJavaScriptに近い簡潔なコードが書けます!それでいて静的型チェックがなされる、スバラシー!!
Javaより9年早いクロージャ(Delegate)の導入
Javaは2014年にJava8でようやくクロージャが導入されました。
一方、C#にはVisual Studio 2005で搭載されたC#2.0の時点で、Javaのクロージャに相当するDelegateという機能がありました。
例としてListの中からemailが[email protected]のデータを探すコードを書いてみます。 Java7までの書き方(いわゆるforおじさんの書き方)
ArrayList users = new ArrayList users.add(...); // データを何件か追加したとする UserInfo foundData = null; for (int i = 0; i < user.size(); i++) { UserInfo user = users.get(i); if (user.getEmail().equals("[email protected]") foundData = user; }
C#だと同じ処理をDelegate(ラムダ式)を使って簡潔に書けます。
var users = new List users.Add(...); // データを何件か追加したとする UserInfo foundData = users.Find(user => user.Email == "[email protected]");
Javaは2014年にクロージャが導入されてようやく、C#と同じような書き方ができるようになりましたが、C#に比べて9年間もの間forおじさんをしなければならなかったわけです。
どの言語を使うかでプログラミングのトレンドについていきやすさが変わるってことです。
ですから、先進的な機能を次々と取り入れているC#の方が断然おすすめなんです!