rksoftware

Visual Studio とか C# とかが好きです

C# 2.0 以降の新機能の確認 - C# 8.0 - 構造体型の readonly インスタンス メンバー

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

構造体型の readonly インスタンス メンバー

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/struct#readonly-instance-members
 構造体のメソッドに readonly をつけられる。(クラスにはつけられない)

public readonly override string ToString() => "";

 プロパティの値を変更するコードはエラーになる。

public struct Point
{
    public double X { get; set; }

    public readonly override string ToString()
    {
        X += X;  // エラー CS1604 読み取り専用であるため 'X' に割り当てできません
        return "";
    }
}

 readonly メソッドの中で、readonly でない getter を呼ぶと警告になる。※自動実装プロパティの getter は readonly なので大丈夫

public struct Point
{
    double _x; public double X { get => _x; set => _x = value; }

    public readonly override string ToString()
    {
        Console.WriteLine(X);  // 警告 CS8656 'readonly' メンバーから readonly 以外のメンバー 'Point.X.get' を呼び出すと、'this' の暗黙のコピーが生成されます。
        return "";
    }
}

C# 2.0 以降の新機能の確認 - C# 7.2 - 拡張メソッドの最初の引数では、その引数が構造体でない限り、in 修飾子を使用することはできません

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

拡張メソッドの最初の引数では、その引数が構造体でない限り、in 修飾子を使用することはできません

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/in-parameter-modifier#limitations-on-in-parameters
 拡張メソッドの this 引数を参照にできる。拡張メソッドの最初の引数では、その引数が構造体でない限り、in 修飾子を使用することはできません。

struct St { }
class Cl { }

static class Extensions
{
    public static void St(in this St st) { ; }
    // public static void Cl(in this Cl cl) { ; } ← class の場合は in 指定できない
}

C# 2.0 以降の新機能の確認 - C# 7.2 - ref 条件式

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

ref 条件式

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/conditional-operator#conditional-ref-expression
 三項演算子で参照(ref)を返せるようになった。

{ // 変数 a と c は同じなので、a への代入で c の出力も変わる
    var (a, b) = (10, 20);
    ref var c = ref (true ? ref a : ref b);
    (a, b) = (11, 21);
    Console.WriteLine($"a:{a} b:{b} c:{c}");    // a: 11 b: 21 c: 11 と出力される
}
{ // 変数 b と c は同じなので、b への代入で c の出力も変わる
    var (a, b) = (10, 20);
    ref var c = ref (false ? ref a : ref b);
    (a, b) = (11, 21);
    Console.WriteLine($"a:{a} b:{b} c:{c}");    // a: 12 b: 21 c: 21 と出力される
}
{ // 参照が返っているので、変数 a の値を直接変更できる
    var (a, b) = (10, 20);
    (true ? ref a : ref b) = 13;
    Console.WriteLine($"a:{a} b:{b}");    // a: 13 b: 20 と出力される
}
{ // 参照が返っているので、変数 b の値を直接変更できる
    var (a, b) = (10, 20);
    (false ? ref a : ref b) = 24;
    Console.WriteLine($"a:{a} b:{b}");    // a: 10 b: 24 と出力される
}

C# 2.0 以降の新機能の確認 - C# 7.2 - 0b または0x の後に桁区切り記号を使用する

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

0b または0x の後に桁区切り記号を使用する

 https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-7#numeric-literal-syntax-improvements
 0x0b の直後に _ を書けるようになった。

// C# 7.1 で書ける
const int A = 0x1_2345;
const int B = 0b1_0101;

// C# 7.2 以降でないとエラー
const int CS72A = 0x_1_2345;
const int CS72B = 0b_1_0101;

C# 2.0 以降の新機能の確認 - C# 7.2 - 末尾以外の名前付き引数

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

末尾以外の名前付き引数

 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments#named-arguments
 引数の順番とあっている位置であれば、より後方に名前付きでない引数があっても名前付き引数にできる。

MyMethod(1, 2, c: 3, 4);         // ← c の位置が順番とあっているので OK
MyMethod(1, 2, d: 3, c: 4);      // ← 名前付きが後方に集まっているので OK
// MyMethod(1, c: 2, b: 3, 4);  // ← c、b の位置が順番とあっていないので NG
MyMethod(d: 1, c: 2, b: 3, a: 4);  // ← 全て名前付きなので OK
// MyMethod(1, c: 2, b: 3, a: 4); // ← a の位置は既に値が書かれている (1) ので NG}

static void MyMethod(int a, int b, int c, int d) { ; }

衝撃の事実! 千葉に対する世間の認識は意外な結果に

衝撃の事実です。

正直、3 番目の選択肢が圧倒的だと確信していたのですが...

ちなみに埼玉の場合は、1 番目の選択肢が圧倒的でした。

rksoftware.hatenablog.com

やはり皆さん千葉にはいったことがあるものなのですね。
東京の名を冠するあのテーマパーク(ドイツ)とかなのでしょうね。

いかがでしたか?

C# 2.0 以降の新機能の確認 - C# 7.2 - private protected アクセス修飾子

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

private protected アクセス修飾子

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/private-protected
 同アセンブリ内の派生クラスでのみアクセスできる。
 次の例では二つの名前空間は別アセンブリにあるとします。

namespace ClassLibrary1
{
    // private protected メソッドを持つクラス
    public class Class1
    {
        private protected void MyMethod() {; }
    }

    // 同アセンブリ内のクラス
    public class Class3 : Class1
    {
        void MyMethod2() { base.MyMethod(); } // ← 同アセンブリ内の派生クラスは OK
    }
}
// 別アセンブリ
namespace AnotherAssemblyClass
{
    // 別アセンブリのクラス
    class AnotherAssemblyClass : ClassLibrary1.Class1
    {
        void MyMethod3()
        {
            // base.MyMethod(); ← これはエラー
        }
    }
}