trsing’s diary

勉強、読んだ本、仕事で調べたこととかのメモ。

読書 スラスラわかるC# 第2版

スラスラわかるC# 第2版

スラスラわかるC# 第2版

C#はかなり昔に入門本を読んでそれ以来必要になった箇所だけ適当につまみ食い。そんなのでも使う頻度は低くやることもちょっとした改修程度だったので困りませんでしたが、最近業務でがっつり使う必要が出てきました。

それでまじめに復習しておきたいなーと思ってたところ、ググったらだいたい出てくるHPの人が著者の本があるということで買いました。
使えるレベルで各機能が紹介されており、つまみ食いだった部分をちゃんと整理することができました。基礎として必要な部分がしっかり載っています。とはいえ深堀はしていないので手の込んだことをしようと思うなら別途調べる必要があります。

C#の復習をしたい人のほか、C#に手を出そうと思ってるほかの言語経験者にとっても良い本になると思います。プログラム初心者にとってはどうだろ?スラスラとはいかないかも。

Visual StudioC#インタラクティブをお供に読み進めるとよいと思います。REPL実行できるので本に書いてあるちょっとしたコードを確認するのにすごく便利。 f:id:trsing:20190328223127p:plain
f:id:trsing:20190328223152p:plain

覚えてた方がよさそうなもの適当にメモ
  • @をつけるとキーワードを変数名として使うことができる
  • スコープが異なる、同じ名前の変数は認められない
    ※メンバーとローカル変数は共存可
{
    {int x = 2;}
    int x = 5;
}
(1,9): error CS0136: ローカルまたはパラメーター 'x' は、その名前が外側のローカルのスコープでローカルやパラメーターの定義に使用されているため、このスコープでは宣言できません。
  • 多次元配列[a,b](要素がaxb個)と配列の配列[a][b](要素が配列である)は別物
  • 匿名型は、他のクラスのプロパティを初期化子に渡す場合にはプロパティ名を省略できる
 class User { 
    public int Id { get; } = 19; 
    public string Name { get; } = "abc"; 
}
 var usr = new User();
 var ukusr = new { usr.Id, usr.Name };
> ukusr
<>f__AnonymousType0#56<int, string>(\{ Id = 19, Name = "abc" })
  • 匿名型は型を明示して書くことはできない
> var u = new { int Level = 12, string Title = "AA" };
(1,15): error CS1525: 'int' は無効です。
(1,19): error CS1003: 構文エラーです。',' が必要です。
(1,31): error CS1525: 'string' は無効です。
(1,38): error CS1003: 構文エラーです。',' が必要です。
> var u = new {  Level = 12,  Title = "AA" };
  • 匿名型コンパイル時には自動的にクラスへと展開される。そのため、dynamicのように動的に実行時にプロパティ名の解決を行うような場合でも、正しく実行することができる
static void OutputTitle(dynamic item)
{ Console.WriteLine(item.Title); }
var x = new { Title = "A", Level = 12 };
OutputTitle(x);
>A
  • tupleはコンパイル時にValueTupleという型へと展開される。このときフィールド名はなくなる。そのため、dynamicのように動的に実行時にプロパティ名の解決を行うような場合、まず動作しない(Item1などにすれば動作する)。
static void OutputTitle(dynamic item)
{
    Console.WriteLine(item.Title);
    //Console.WriteLine(item.Item2);
}
static void Main(string[] args)
{
    (int level, string Title) p = (12, "A");
    Console.WriteLine(p.Title);
    OutputTitle(p); //NG。'Title'の定義がありません。Item2ならOK
}
  • C#7.0以降に追加された新しい文法、_がそのスコープから利用可能な識別子として存在しない場合、アンダースコアを値の破棄として使うことができる
var (w,_,_,z) = (10,20,30,40);
  • オーバーロード呼び出しの優先順位は
    オプションなし>オプションあり>可変長引数
  • readonly:クラスのフィールドでのみ宣言可。staticの有無を変えられる。コンストラクター内で値を書き換え可能。new可能。コンパイル結果は変数と同様。
    const:ローカル変数でも宣言可。常にstatic扱い。宣言時のみ初期化可能。インスタンスをnewで生成するものには使えない。コンパイル結果はリテラルと同様。

  • 静的な型はtypeof(クラス名)。静的とはコンパイル時に型が確定するという意味。
    動的な型は変数名.GetType()。動的とはコンパイル時には型が確定せず、実行時に変化する可能性があるもの。

> class Base { }
> class Derived : Base { }
> Base a = new Base();
> a.GetType()
[Submission#3+Base]
> Base b = new Derived();
> b.GetType()
[Submission#4+Derived]
  • コンストラクタが呼ばれる順番は基底→継承
    ※呼び出される基底クラスのコンストラクターは引数なしのコンストラクター。引数付きのコンストラクターを呼び出すためには、明示的に基底クラスのコンストラクターを呼び出す必要がある。
  • キャスト式:型変換できない場合は例外を返す
    as演算子:型変換ができない場合には結果がnullになる
    is演算子:左辺の変数が右辺の型にキャスト可能ならばtrue、不可ならばfalseを返す
  • 既定値default(T) 値型:0、参照型:null
  • IEnumerableインターフェイスを使う場合:データを全件取得した上で、プログラム中で加工(データ全件分の通信量)
    IQueryableインターフェイスを使う場合:データを外部のシステムにデータの加工まで依頼し、必要なデータのみ取得(加工済みデータ分の通信量)