講義メモ 後半

p.62 dynamic型

・C#バージョン4.0以降において、型が未確定の変数を定義可能になった。
・この場合の型がdynamic型で、var型の上位概念に当たる。
・dynamic型の変数は代入によって型が決まるので、便利だが実行効率はvar型より低くなる懸念がある
・定義済のdynamic型変数に、異なる型の値を代入すると型を変更できる(varとは異なりエラーにならない)
・ただし、内部的に、Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Createを用いるので、
 プロジェクトに下記の参照指定が必要
 ⇒ Microsoft.CSharp
・手順
 ①ソリューションエクスプローラで「参照」を右クリックし「参照の追加」
 ②「Microsoft.CSharp」のチェックをオンにして「OK」
・なお、var型と同様に、初期化によって型を決めることもできる

アレンジ演習:p.63 dynamic01.cs

・「z = 1.25;」の前にz.GetType()を実行するとどうなるか確認しよう
・後で、x,y,zに別の型の値を代入できるかどうか確認しよう
・var型、dynamic型の定数が定義可能か確認しよう

作成例

//アレンジ演習:p.63 dynamic01.cs
using System;
class Dynamic01 {
  public static void Main() {
    dynamic x = 10, y = "abc", z; //この時点でxはInt32、yはString、zは未定
    //Console.WriteLine("z ---- {0}", z.GetType()); //zは未定なので文法エラーになる
    z = 1.25; //この時点でzはDouble
    Console.WriteLine("x ---- {0}", x.GetType()); //System.Int32
    Console.WriteLine("y ---- {0}", y.GetType()); //System.String 
    Console.WriteLine("z ---- {0}", z.GetType()); //System.Double
    //【以下追加】
    x = 10;
    y = 'a';
    z = 100M;
    Console.WriteLine("x ---- {0}", x.GetType()); //System.Int32
    Console.WriteLine("y ---- {0}", y.GetType()); //System.Char 
    Console.WriteLine("z ---- {0}", z.GetType()); //System.Decimal
    //const var c = 10; //var型の定数は不可(文法エラー)
    //const dynamic d = 10; //dynamic型の定数は不可(文法エラー)
    const dynamic e = null; //ただし、値がnullであれば可能だが…
    Console.WriteLine("e ---- {0}", e.GetType()); //実行時エラーになってしまう
  }
}

p.64 スコープ

・スコープは「視野」「見える範囲」のことで、変数などの識別子の有効範囲を示す
・基本的に識別子が定義されたブロック{…}内が、そのスコープになる
・入れ子のブロックがある場合、内側のブロックもスコープに含まれる
・なお、C/C++などではスコープが異なれば同名の変数などの識別子が使えるが、C#では禁止。

p.64 scope01.cs 補足

・このコードで分かるとおり、プログラマが自由にブロックを記述できる
・ブロックを記述することで、変数などの識別子のスコープを制限できる
・但し、必要がないスコープの記述はプログラムの可読性を大きく損なうので注意

p.64 scope01.cs

//p.64 scope01.cs
using System;
class scope01
{ //クラスのブロック
    public static void Main()
    { //Mainメソッドのブロック
        int a = 10;
        Console.WriteLine("a = {0}", a); //ここではaのみ有効
        { //プログラマが作ったブロック
            int b = 5;
            Console.WriteLine("a = {0}, b = {1}", a, b); //ここではa.bが有効
            { //プログラマが作ったブロック
                int c = 1;
                Console.WriteLine("a = {0}, b = {1}, c = {2}",
                    a, b, c); //ここではa.b,cが有効
            } //cが有効なのはここまで
            //ここではcは見えません
            Console.WriteLine("a = {0}, b = {1}",
            a, b); //ここではa.bが有効
        } //bが有効なのはここまで
        //ここでは、b,cは見えません
        Console.WriteLine("a = {0}", a); //ここではaのみ有効
    }
}

p.65 3.12 型変換

・その型が扱える値の範囲を「型の大きさ」という。
 例: sbyte型の大きさは-127~126
・型が大きい変数に、型が小さい変数や値を代入すると、自動的に型が大きいほうに合わせてくれる
・これを暗黙の型変換という
 例: int a; short b = 5; a = b; //bの値5を32ビット整数に暗黙変換して代入する
・よって、暗黙の型変換によるトラブルや誤差の発生は想定しなくて良い
・対して、型が小さい変数に、型が大きい変数や値を代入すると、文法エラーになる
・しかし、型が大きい変数や値であっても、型が小さい変数に代入できるのであれば、プログラマの責任で強制的に代入できる
・このための、強制的な型変換をキャスト(あるいは、型キャスト)という
・書式: (型)変数や値
 例: short a; int b = 5; a = (short)b; //bの値5を16ビット整数に強制的に変換して代入する
・【正誤】p.66 上から5行目「b = (byte)2;」⇒「b = (byte)a;」

アレンジ演習:p.66 cast01.cs

・【注記】このプログラムは「Console.Write/WriteLine」がまったくないので実行しても何も表示されない
・bの値と、(byte)aの型を表示しよう
・型の大きさを超える値のキャストは可能かを確認しよう(例:(byte)5000)
・uint型とint型でのキャストは可能かを確認しよう
・ushort型とint型でのキャストは可能かを確認しよう
・実数リテラル3.9をint型にキャストするとどうなるか確認しよう
・整数3と4の平均値をdouble型へのキャストを用いることで小数点以下まで表示しよう

提出:アレンジ演習:p.66 cast01.cs(途中でもOK)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です