2009年10月31日

【var変数】 var変数記事一覧【まとめ】

C#3.0のvar変数に関する記事のまとめです。

1.【var変数】 新しい変数宣言var
  var変数とは?

2.【var変数】 varのメリット
  varはどのような場面で使うのが有効か?

3.【var変数】varが有効な場面
  varが特に有効と思われるパターンを紹介



次回は、yield return / yield breakについて書く予定です。
ラベル:var変数
posted by 吾一 at 23:06| 3. var変数 | このブログの読者になる | 更新情報をチェックする

2009年10月27日

【var変数】varが有効な場面

前回のつづきになりますが、var変数が有効な場面をいくつか挙げてみます。
いずれも有効な場面と紹介されることが多いパターンですが、必ずvarを使ったほうが良い訳ではないです。
あくまで参考までに

for文のループ変数に使うパターン
class Program
{
    static void Main(string[] args)
    {
        for (var i = 0; i < 10; i++)
        {
             // 処理
        }
    }
}
varじゃなくて、intで良いじゃないかという意見は多いと思います。
タイプ数も同じだからあまり利点は無いのですが、ただ単にループすることが目的で、
変数iを一切参照しない場合には、型にこだわりが無いことが明確になるので良いかもしれません。

foreach文で使うパターン
class Program
{
    static void Main(string[] args)
    {
        // Dictionaryオブジェクトに値をセット
        Dictionary<int, string> dict = new Dictionary<int, string>();
        dict.Add(1, "一番");
        dict.Add(2, "二番");
        dict.Add(3, "三番");

        foreach (var kvp in dict)
        {
            // KeyとValueを表示
            Console.WriteLine(kvp.Key + kvp.Value);
        }
    }
}
結構おすすめに挙げられることが多いパターンです。
foreach文の見通しが良くなるのがメリットですね。
デメリットは、型が一見して分からなくなることです。
上の例のkvp変数は、本来KeyValuePair<int, string>型なのですが、これを長くて冗長だからvarとするか、
型が分かりにくいからKeyValuePair<int, string>と書くかは、どっちが良いか微妙なところです。
邪道ですが、列挙される型がすぐに分からない時に、一時的にvarと書いてIDEで型を確認するという使い方は有りだと思われます。

usingステートメントで使うパターン
class Program
{
    static void Main(string[] args)
    {
        // usingステートメントで、StreamWriterをnewして使用する
        using (var sw = new StreamWriter(@"log.txt", true, Encoding.GetEncoding("Shift_JIS")))
        {
            sw.WriteLine("ファイルに書き込み");
            sw.Close();
        }
    }
}
varを使わないとクラス名が2回繰り返されるパターンです。
見通しが良くなり、型も分かりにくくならないので積極的に使えそうです。
3つのパターンの中では一番おすすめです。

var変数の先頭記事へ var変数の次の記事へ
ラベル:var変数
posted by 吾一 at 23:00| 3. var変数 | このブログの読者になる | 更新情報をチェックする

2009年10月24日

【var変数】 varのメリット

今回は、なぜvarを使うのか?どのような利点があるのか?を考察します。
実を言うとvarの使い方は、絶対の正解があるわけではないので少し難しいところです。
主な使い方を順番に見ていきましょう。

(1)組み込み型に対してvarを使う
class Program
{
    static void Main(string[] args)
    {
        // intの代わりにvarを使う
        var num = 100;
        // stringの代わりにvarを使う
        var str = "文字列";
    }
}
(2)クラス名に対してvarを使う
class Program   
{   
    static void Main(string[] args)   
    {   
        // List<int>の代わりにvarを使う
        var list = new List<int>();
        // StringBuilderの代わりにvarを使う
        var builder = new StringBuilder();
    }   
}
(3)匿名型に対してvarを使う
class Program
{
    static void Main(string[] args)
    {
        // 匿名型にvarを使う
        var Gogh = new { Name = "ゴッホ", Age = 37, Country = "オランダ" };
        var Monet = new { Name = "モネ", Age = 86, Country = "フランス" };
    }
}
匿名型というのは、クラス名を持たない匿名クラスのことです。
読み出し専用(getのみ)のプロパティだけで構成されるという特徴があります。
この匿名型を宣言する場合だけは、必ずvarで変数を宣言しなければなりません。
ここだけは、議論の余地が無く誰もが同じ書き方になります。

ただ(2)のクラス名の代わりにvarを使う書き方や、
(1)の組込型の代わりに使う書き方は人によって意見が大きく割れるところです。
class Program   
{   
    static void Main(string[] args)   
    {   
        // 通常の定義方法
        int a = 100;
        string b = "文字列";
        double c = 1.00d;
        
        // 組み込み型の代わりにvar
        var a = 100;
        var b = "文字列";
        var c = 1.00d;
    }   
}
組み込み型の代わりに使うvarは、結構抵抗がある人が多いみたいです。
今までの書き方に慣れている人にとっては、何のメリットがあるのか疑問に思いますよね。
メリットとしては、変数がvarで統一されてる方が変数名の位置が揃って見えるので、コードがスッキリ見えるところですね。
デメリットは、パッとコードを見た時に右辺の値を見ないと型が分からないのが若干手間に感じるところです。
あと一番大きいのが、今までの見慣れた書き方と掛け離れるって事だと思います。
個人的な考えでは、自分しか読まないコードなら組み込み型にvarを使うのもありだと思うのですが、
会社などチームで開発するなら、今のところは使わない方が無難かなと思います。(今後考えが変わる可能性はありますが)
class Program   
{   
    static void Main(string[] args)   
    {   
        // 通常の定義方法
        List<int> list = new List<int>();
        Dictionary<int, string> dict = new Dictionary<int, string>();
        StringBuilder builder = new StringBuilder();

        // クラス名の代わりにvar
        var list = new List<int>();
        var dict = new Dictionary<int, string>();
        var builder = new StringBuilder();
    }   
}
クラス名の代わりにvarを使うのはどうでしょうか?
通常の定義方法では、変数定義とnewの後で2箇所同じクラス名が出てくるので少し冗長な感じを受けますが、varの方はコードがスッキリして、メリットが際立ちます。
右辺を見れば、クラス名が書かれてますからデメリットもあまり目立たないような感じがします。
個人的に、この書き方は使っていった方が見やすくて良いかなと思うのですが、どうでしょうか。


いずれもvarの良し悪しは慣れによるところが大きいようですので、今後は全てvarで統一するような時代が来るのかも知れません。
他の方のブログとかを見てる感じでは、使っている内に違和感がなくなって考えが180度変わったという方が結構居ました。
変な先入観を持たずに、しばらく使ってみて判断するのが一番なのかもしれません。

var変数の先頭記事へ var変数の次の記事へ
ラベル:var変数
posted by 吾一 at 23:26| 3. var変数 | このブログの読者になる | 更新情報をチェックする

2009年10月22日

【var変数】 新しい変数宣言var

今日から新しい章、var変数に入ります。
varとは、明示的に型名を書くことなく宣言できる変数宣言です。

class Program
{
    static void Main(string[] args)
    {
        // var変数の定義
        var num = 100;
        var str = "文字列";
    }
}
のように変数宣言して使います。
varには制限があり、ローカル変数でしか使うことが出来ません。
また、もう一つ重要な制限があります。
それは、varは必ず初期化と共に宣言されなければならないというものです。

class Program
{
    static void Main(string[] args)
    {
        // ↓これはコンパイルエラー
        var abc;
        //エラー CS0818: 暗黙的に型指定されたローカル変数を初期化しなければなりません
    }
}
varはなぜ必ず初期化しなければならないのでしょうか?
それは、var変数は宣言時に型を確定させなければならないからです。
つまりvar変数は、どんな型でも受け入れるVariant型ではなく
宣言時には必ずある特定の型に決定されます。
(初期化する値が整数であればint型、文字列ならstring型になる)
varが使用されていても、C#のコンパイル時の強力な型チェックは守られるのです。
見た目だけで判断すると、JavaScriptの変数の様に何でも代入できそうに見えますが、
実際は普通に宣言した変数と何ら変わらないということです。

class Program
{
    static void Main(string[] args)
    {
        // abcは int型に確定
        var abc = 100;
        
        // ↓これはコンパイルエラー
        abc = "文字列";
        // エラー CS0029: 型 'string' を型 'int' に暗黙的に変換できません。
    }
}
じゃあどういう場面で使うと便利なの?というのは次回に回すとして、
今回は、var変数の型が確定される仕組みを表したサンプルコードを示します。
以下のコードを御覧ください。

class Program
{
    static void Main(string[] args)
    {
        // aは int型
        var a = 0;
        // bは string型
        var b = "文字列";
        // cは object型
        var c = new object();

        // dは int型
        var d = 2147483647;    // int型の最大値
        // eは uint型
        var e = 2147483648;    // int型の最大値 + 1
        // fは int型
        var f = -2147483648;   // int型の最小値
        // gは long型
        var g = -2147483649;  // int型の最小値 - 1
        // hは long型
        var h = 9223372036854775807;  // long型の最大値
        // iは ulong型
        var i = 9223372036854775808;   // long型の最大値 + 1

        // jは float型(サフィックスがfまたはFの場合はfloat)
        var j = 1.0f;
        // kは double型(サフィックスがdまたはDの場合はdouble)
        var k = 1.0d;
        // lは decimal型(サフィックスがmまたはMの場合はdecimal)
        var l = 1.0m;
        // mは double型(サフィックスなしの実数はdouble)
        var m = 1.0;
    }
}
<暗黙的に確定される型の法則>
サフィックスの無い整数は、int、uint、long、ulongのうち、その値を表すことが出来る最初の型になる。
整数のサフィックスがUまたはuの場合、uintまたはulongのうち、その値を表すことが出来る最初の型になる。
整数のサフィックスがLまたはlの場合、longまたはulongのうち、その値を表すことが出来る最初の型になる。
整数のサフィックスがUL, Ul, uL, ul, LU, Lu, lU, またはluの場合、ulong型になる。
実数のサフィックスがFまたはfの場合、float型になる。
実数のサフィックスがDまたはdの場合、double型になる。
実数のサフィックスがMまたはmの場合、decimal型になる。


var変数の次の記事へ
ラベル:var変数
posted by 吾一 at 01:06| 3. var変数 | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。