C#基本文法


JS経験者が3ヶ月ほどC#を学んで、
個人的に気になった部分のみピックアップしたメモ



## 論理演算子

### ブロークンバー`|`と`||`の違い

```csharp
static bool isWoman(string _sex){
    Console.WriteLine("isWomanを実行");
    return _sex == "Woman";
}
static bool isOlder(int _age){
    Console.WriteLine("isOlderを実行");
    return _age >= 60;
}
public static void Main(string[] args)
{
    Console.WriteLine( isWoman("Woman") | isOlder(70) ); // isOlder()を実行
    Console.WriteLine( isWoman("Woman") || isOlder(70) ); // isOlder()を実行しない
}
```


## キャスト

```csharp
// double -> int
int n = (int)(100 * 1.12345);

// int -> string
string s = n.ToString();

// string -> int
int i = int.Parse(s);
```



## オーバーロード

同名のメソッドを複数定義することが可能
引数および返り値が異なる必要がある

```csharp:OverloadTest.cs
public class OverloadTest
{
	public string Hoge(string s)
	{
	    Console.WriteLine("Hoge1 func");
	    return s;
	}
	public int Hoge(int a)
	{
	    Console.WriteLine("Hoge2 func");
	    return a;
	}
	public int Hoge(int a, int b)
	{
	    Console.WriteLine("Hoge3 func");
	    return a + b;
	}
}
```

```csharp:Program.cs
public static void Main(string[] args)
{
	OverloadTest ot = new OverloadTest();
	Console.WriteLine(ot.Hoge("test"));
	Console.WriteLine(ot.Hoge(1));
	Console.WriteLine(ot.Hoge(1,2));
}
```

```md:出力結果
Hoge1 func
test
Hoge2 func
1
Hoge3 func
3
```



## プロパティ

http://ufcpp.net/study/csharp/oo_property.html

外部からフィールドにアクセスできる機能
フィールドを取得・変更するメソッド＝アクセサー（getter, setter）

```csharp
class Person
{
    private string _name;

    // 変数名に合わせたキャメルケース
    public string Name {
        // 片方だけ設定して、読み込み専用、書き込み専用にもできる
        // setter
        set {
            _name = value; // valueに外部から代入された値が格納される
        } 
        // getter
        get {
            return _name;
        }
    }
}
```

```csharp:同じことを一行で書ける
class Person
{
	public string Name { get; set; }
}
```

```csharp:初期化も可能
class Person
{
	public string Name { get; set; } = "鈴木";
}
```

```csharp:使ってみる
Person p1 = new Person();
p1.Name = "佐藤";
Console.WriteLine("名前は{0}です", p1.Name);
```




## 修飾子

### アクセス修飾子

https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/access-modifiers

|修飾子|意味|
|---|---|
|public|どこからでも|
|internal|同じアセンブリから（作成しているプログラム全部から）|
|protected|そのクラス内および派生クラス|
|private|そのクラス内のみ|


### virtual/override(new)

https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords

サブクラスでスーパークラスのメソッドをオーバーライドする

```csharp
public class MyObject {
    /*
     * オーバーライドされる側
     */
    public virtual void sayHi() {
        Console.WriteLine($"say hi from MyObject!");
    }
}

public class EnchancedMyObject: MyObject{
    /*
     * オーバーライドする側
     * + override -> 上書き
     * + new -> 新しいメソッドを追加
     */
    public override void sayHi() {
        Console.WriteLine($"say hi from EnchancedMyObject!");
    }
}
```

### 静的/抽象/部分クラス

#### 静的（static）クラス
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/static

インスタンスを生成しないクラス
ex. 計算だけするクラス

#### 抽象（abstract）クラス
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/abstract

それぞれの派生クラスに必ずxxxというメソッドを実装する（オーバーライドする）ことを保証させるクラス
このクラス自体はインスタンスを生成しない

```csharp
abstract class AbstractClass {
    public abstract void sayHi();
}

class ConcreateClass: AbstractClass {
    // オーバーライドしないとエラーが出る
    public override void sayHi() {
        Console.WriteLine("override abstract class method!");
    }
}
```

#### 部分（partial）クラス
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/partial-type

いくつでも同じ名前のクラスをつくれて、すべてをまとめて１つのクラスとして機能する
クラスの中身が膨大になったときに分割するために使う

```csharp
public partial class PublicClass {
    public string name = "public class";
}
public partial class PublicClass {
    public int age = 20;
    public void showInfo() {
        Console.WriteLine($"name:{name}, age:{age}");
    }
}
```



## インターフェース

http://ufcpp.net/study/csharp/oo_interface.html

- インターフェースはクラスではないが、クラスの一部分を切り取るイメージ
- 基本的にクラスの多重継承はできないが、インターフェースは多重継承のようなことが可能

```csharp:CellPhone.cs
interface IPhone
{
    void Call(string number);
}
interface IMail
{
    void Send(string address);
}
interface IBrowser
{
    void Search(string word);
}

// 電話、メール、ブラウザのインターフェースを実装した、携帯電話クラスをつくる
class CellPhone: IPhone, IMail, IBrowser {
    public void Call(string number) {
        Console.WriteLine(number + "に電話をかける");
    }
    public void Send(string address) {
        Console.WriteLine(address + "にメールを送る");
    }
    public void Search(string word) {
        Console.WriteLine(word + "をブラウザで検索する");
    }
}
```

```csharp
// 携帯電話
CellPhone cp = new CellPhone();
cp.Call("090-123-4567");
cp.Send("sample@gmail.com");
cp.Search("hoge");

// キャストして機能を限定する
IBrowser ib = (IBrowser)cp;
ib.Search("hoge[from ib]"); // 検索しかできない

// インターフェースを実装しているクラスは、
// 実装しているインターフェースの型に変数を入れられる
IMail im = new CellPhone();
im.Send("sample@gmail.com[from im]"); // メールしか送れない
```



## デリゲート

http://ufcpp.net/study/csharp/sp_delegate.html

他クラスのメソッドを参照するための型
イベントハンドラを参照することが多い

```csharp
// デリゲートの宣言
delegate void SomeDelegate(int i);

public class DelegateTest
{
    public DelegateTest()
    {
        // 自クラスのメソッドを追加
        SomeDelegate a = new SomeDelegate(FuncA); // FuncAを追加
        a += new SomeDelegate(FuncB); // FuncBを追加

        // 他クラスのメソッドを追加する
        DelegateTest2 dt2 = new DelegateTest2();
        a += new SomeDelegate(dt2.FuncC); // FuncCを追加

        // 引数を渡す場合は同じ型でなければならない
        a(10);
    }
    void FuncA(int i)
    {
        Console.WriteLine("call DelegateTest FuncA, {0}", i);
    }
    void FuncB(int i)
    {
        Console.WriteLine("call DelegateTest FuncB, {0}", (i * 2));
    }
}

class DelegateTest2 {
    public void FuncC(int i)
    {
        Console.WriteLine("call DelegateTest2 FuncC, {0}", (i / 2));
    }
}
```



> 参考
https://docs.microsoft.com/ja-jp/dotnet/csharp/
http://ufcpp.net/study/csharp/
http://dotinstall.com/lessons/basic_csharp
http://csharp.sevendays-study.com/