C# で自動プロパティを作成する

Syed Hassan Sabeeh Kazmi 2024年2月15日
  1. C# でクラスを使用して Auto プロパティを実装する
  2. Mono.Reflection ライブラリまたは NuGet パッケージを使用して、C# で Auto プロパティのバッキング フィールドに値を割り当てる
  3. C# で Auto プロパティを変更するクラス オブジェクトを作成する
  4. C# でカプセル化を使用して読み取り専用または書き込み専用の自動プロパティを作成する
C# で自動プロパティを作成する

いつでも変数をプロパティにリファクタリングでき、その逆も可能です。 リフレクションに依存してデータをバインドする場合は、すべてのプロパティを使用する方が簡単であるため、単純なプロパティを作成する正当な理由はたくさんあります。 このチュートリアルでは、auto プロパティに関連するすべてのことと、C# でそれを作成する方法を学習します。

最新の C# プログラミングでは、自動プロパティを使用することは優れたプラクティスであり、パフォーマンスとベスト プラクティスを維持しながらコード記述の効率を維持するための最良のオプションです。

これらのプロパティは通常、メソッドを表しますが、インターフェイスに実装すると問題なく機能します。 これらのプロパティは、それらを実装するインターフェイス、クラス、または名前空間内に特定のメソッドが存在することを保証するための契約として機能します。

C# でクラスを使用して Auto プロパティを実装する

自動プロパティを初期化する適切な方法は、クラスを使用することです。

public class my_class {
  public int my_property { get; set; }
}

このようにして、自動プロパティが意図を伝え、一貫性を確保するため、コードはより読みやすく、理解しやすくなります。 また、これらは get メソッドと set メソッドのペアを定義する最も簡単な方法です。

コードが進化し、別のロジックを導入しても、コードを再コンパイルする必要がないため、多くの場合、自動プロパティを定義する最良の方法と見なされます。 さらに、auto プロパティは、public string new_property {get; set;} そして、デフォルトでコンパイラに残りを生成させます。

using System;
using System.Windows.Forms;

namespace auto_property {
  public class NetworkDevice {
    public string IP { get; set; }  // custom types | represent elements and belongs to the property
    public string drr_add { get; set; }
    public string num_serial { get; set; }
  }

  // pre-defined part of the Windows Form
  public partial class Form1 : Form {
    public Form1() {
      // initialize the design or other components created at design time
      InitializeComponent();
    }

    // represents the on-click event for the button to create the auto property
    private void button1_Click(object sender, EventArgs e) {
      NetworkDevice new_device = new NetworkDevice();
      new_device.IP = "Red_dead Search 12-D Class A";
      new_device.drr_add = "NYC, New York";
      new_device.num_serial = "S11-E2237654-C";

      MessageBox.Show(
          $"The device name: {new_device.IP} \nThe location: {new_device.drr_add} \nThe serial: {new_device.num_serial}",
          "Auto Property", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    }
  }
}

出力:

The device name: Red_dead Search 12-D Class A
The location: NYC, New York
The serial: 511-E2237654-C

C# 自動プロパティ - クラス

C# バージョン 3.0 以降、オブジェクト指向プログラミングのジレンマはなくなりました。 private で行をスキップでき、get および set メソッドの定義も必要ありません。

結論として、自動プロパティは多くのプログラマーがそれらを認識するのに役立ち、その結果、保守可能なコードが作成されました。 コンパイラが各フィールドを完全に処理するため、フィールドを変更するために get および set メソッドのフィールド宣言を使用することは、主要な要件ではありません。

デフォルトでは、プライベート フィールドを作成または生成し、マッピングを保証するのは、コンパイラの機能です。 さらに、自動プロパティに属する特定のフィールドの読み取りと書き込みを可能にするために、get および set メソッドを設定します。

Mono.Reflection ライブラリまたは NuGet パッケージを使用して、C# で Auto プロパティのバッキング フィールドに値を割り当てる

自動プロパティの作成は、プロパティ アクセサーに追加または詳細なロジックを必要とせずにプロパティを作成するためのより具体的な方法です。

自動プロパティの匿名バッキング フィールドは、プロパティの get および set メソッドを使用して変更できます。 プロパティ宣言を使用すると、オブジェクトを作成できるコードを記述し、コンパイラでプライベート バッキング フィールドを作成できるようになります。

一般に、コンパイラによって生成されたバッキング フィールドがある場合、プロパティは自動です。これにより、バッキング フィールドの値を返すか、それに代入する必要があるプリミティブなゲッターとセッターを作成する必要がなくなります。 その構文は、一般的なプロパティを作成するよりもはるかに短く、パブリック クラスと get および set メソッドを使用したパブリック文字列が必要です。

CompilerGenerated 属性は、その名前がユーザーに表示されるため auto プロパティを一意にしますが、コンパイラは get および set アクセサーの本体を生成します。 自動プロパティのバッキング フィールドに値を割り当てることができます。 ただし、パフォーマンスに影響を与え、セキュリティと保護が低下するため、これは推奨されず、ベスト プラクティスとは見なされません。これにより、ある意味で、これらのプロパティを最初に作成する目的が失われます。

using System;
using System.Windows.Forms;

using Mono.Reflection;  // include after installing `Mono.Relection 2.0.0` NuGet package for your C#
                        // project

namespace auto_property {
  public class mono_exp {
    public const string name_official = "Great organization name with an excellent track record!";

    public string name_company { get; } = name_official;

    private string code_registration;

    // to assign new values to the `code_registration`
    public string pri_reg {
      get { return code_registration; }   // read
      set { code_registration = value; }  // write
    }

    // to read-only as an output
    public string name_display {
      // return the new value of `code_registration`
      get {
        return name_company + ": " + code_registration;
      }
      set {}  // empty
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      var company_name =
          typeof(mono_exp).GetProperty(nameof(mono_exp.name_company)).GetBackingField();

      var registration_no =
          typeof(mono_exp).GetProperty(nameof(mono_exp.pri_reg)).GetBackingField();

      MessageBox.Show($"{company_name.Name}, {registration_no.Name}", "Auto Property",
                      MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    }
  }
}

出力:

<name_company>k__BackingField, code_registration

C# 自動プロパティ - Mono.Reflection

いくつかのヘルパー メソッドを記述したり、リフレクションを使用して値を割り当てたり、ユニット テスト時にオブジェクトに期待される状態を割り当てたりすることができます。 セッターを呼び出さずにクラスの予期される状態を直接設定することをお勧めします。これを行うと、コードのテストや最適化において重要ではない一連のイベントが開始される可能性があるためです。

自動プロパティに値を割り当てる前に、そのバッキング フィールドを見つけることが重要です。 1つのアイデアは、Jb Evain による BackingFieldResolver を使用し、Mono.Reflection NuGet パッケージをソリューションに追加して、このライブラリを追加することです。

バッキング フィールドを検索するたびに ArgumentException をスローして、コードをより効率的にし、可読性を高めます。

C# で Auto プロパティを変更するクラス オブジェクトを作成する

自動プロパティを使用すると、アプリケーション プログラミング インターフェイスを将来にわたって保証し、データ バインディングを可能にすることができます。 自動プロパティの実装の概念は、クラス オブジェクトを使用して完全に理解できます。オブジェクトに変更を加えることで、自動プロパティのさまざまな動作に対する理解を深めることができます。

プロパティを変更およびアクセスするための自動プロパティ アクセサー (get および set メソッド) が C# 3.0 で導入されました。これらのプロパティの機能は、C# 9.0 バージョンでの init アクセサーの導入によりさらに強化されています。 インターフェイスで自動プロパティを宣言できないため、クラスになるボディを定義する必要があり、自動プロパティから関数または属性を呼び出すには、新しいクラス オブジェクトを作成する必要があります。

クラス オブジェクトは、インターフェイスの自動プロパティ要素にアクセスするのに役立ち、開発者に多くの可能性をもたらします。 自動プロパティとその要素を初期化する 1つの方法は、次を使用することです。

public string {get; set;} = "example_text"

そうすることで、複雑なクラスに重要な動作 (メソッドを含む動作) とデータを含めることもできます。

using System;
using System.Windows.Forms;

namespace auto_property {
  public class new_element {
    public double element_ip { get; set; }
    public string element_serial { get; set; }
    public int element_drr { get; set; }

    public new_element(double IP_add, string ser_no, int counter_ddr) {
      element_ip = IP_add;
      element_serial = ser_no;
      element_drr = counter_ddr;
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      new_element element_new = new new_element(2860.01, "Red_Dead", 9743822);
      element_new.element_ip += 499.99;

      MessageBox.Show(
          $"{element_new.element_ip}, {element_new.element_serial}, {element_new.element_drr}",
          "Auto Property", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    }
  }
}

出力:

3360, Red_Dead, 9743822

C# 自動プロパティ - クラス オブジェクト

プロパティアクセサーが追加のロジックを必要としない場合、自動プロパティが使用され、 public int some_property {get; set;}。 自動プロパティを使用すると、その背後にある設計哲学として簡潔で具体的なものを作成できます。たとえば、フィールドを public として公開することはなく、プロパティを介して常にすべてにアクセスするなどです。

C# の 3.0 以降のバージョンでは、クライアント コードでオブジェクトを作成および変更できるため、より簡潔なプロパティ宣言と高パフォーマンスの自動プロパティの作成が可能になります。 Visual Studio での開発では、getset でブレークポイントを使用できます。これは、プロパティの呼び出し元との契約を破ることなくそれらを変更し、明らかでない変更のソースのためにリフレクションを使用して変更できるためです。

C# でカプセル化を使用して読み取り専用または書き込み専用の自動プロパティを作成する

暗号化により、自動プロパティの処理と変更が容易になりますが、クラス内で変更を加えることができます。また、リフレクションを介してプライベート セッターにアクセスできるため、クラスは不変ではありません。 C# 6.0 以降では、真の read-only および write-only 自動プロパティを作成できます。

read-only 自動プロパティは、コンストラクターの外では変更できない不変のプロパティにすることができます。

public string new_property { get; }
public new_class() {
  this.new_property = "something";
}

その後、コンパイル時のこの不変 (読み取り専用) プロパティは次のようになります。

readonly string new_name;
public string new_property {
  get { return this.new_name; }
}
public new_class() {
  this.new_name = "something";
}

その結果、コードを最適化し、余分なコードを終了することで、多くの時間を節約できます。 フィールド/変数をプライベートとして宣言し、パブリック get および set メソッドを提供してプライベート フィールドの値にアクセスして更新することにより、自動プロパティを成功させるには、カプセル化の基本的な理解が必要です。

セキュリティの向上と柔軟性の向上に加えて、自動プロパティを使用すると、プロパティを読み取り専用 (get メソッドのみを使用) または書き込み専用 (set メソッドのみを使用) にすることができます。

自動プロパティに直接値を代入することは、クリーンで美しいように思えます。 それでも、これは錯覚であり、コードをリリース モードでビルドし、プログラム デバッグ データベースを削除し、結果のライブラリを逆コンパイラで開くと、違いがわかります。

using System;
using System.Windows.Forms;

namespace auto_property {
  public class new_element {
    /*

    // write only auto property example

    private int _int;
    public int _newint
    {
        set { _int = value; }
    }

     */
    public double element_ip { get; set; }
    public string element_serial { get; }  // read-only
    public int element_drr { get; }        // read-only

    public new_element(double IP_add, string ser_no, int counter_ddr) {
      element_ip = IP_add;
      element_serial = ser_no;
      element_drr = counter_ddr;
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      new_element element_new = new new_element(2860.01, "Red_Dead", 9743822);
      element_new.element_ip += 499.99;  // modification

      MessageBox.Show(
          $"{element_new.element_ip}, {element_new.element_serial}, {element_new.element_drr}",
          "Auto Property", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    }
  }
}

出力:

3360, Red_Dead, 9743822

C# 自動プロパティ - カプセル化

変数とプロパティの間には多くの摩擦があるため、Kevin Dente は新しい構文 public property int example_var; を導入しました。これは、プロパティが変数とまったく同じことを行いますが、可視性をより細かく制御できるためです。 自動プロパティは軽量である必要があり、多大な労力が必要な場合は明示的なメソッドにリファクタリングできます。

auto プロパティは通常のプロパティよりも効果的であり、通常のプロパティと同じ最適化も受け取るため、アンチパターンではありません。 唯一の違いは、バッキング フィールドが自動的に生成されることです。 このチュートリアルでは、C# で auto プロパティを定義、最適化、および変更する方法を説明しました。

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

関連記事 - Csharp Property