回答:
プロパティはフィールドを公開します。フィールドは(ほとんどの場合)クラスに対してプライベートにして、getおよびsetプロパティを介してアクセスする必要があります。プロパティは、クラスを使用するものからアクセスされる外部の方法に影響を与えずにフィールドを変更できるようにする抽象化のレベルを提供します。
public class MyClass
{
// this is a field. It is private to your class and stores the actual data.
private string _myField;
// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}
// This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
// used to generate a private field for you
public int AnotherProperty{get;set;}
}
@Kentは、プロパティはフィールドをカプセル化する必要はなく、他のフィールドで計算を行ったり、他の目的に役立つ可能性があることを指摘しています。
@GSSは、プロパティにアクセスしたときに検証などの他のロジックを実行できることも指摘しています。これは別の便利な機能です。
string
である場合、私の契約は、最大20億文字までの文字を割り当てることです。プロパティがの場合DateTime
、私の契約は、DateTimeの制限内の任意の数値を割り当てます。作成者が制約をセッターに追加した場合、それらの制約は伝達されません。ただし、代わりに、作成者が型をからstring
に変更したSurname
場合、新しいSurnameクラスが制約を伝え、プロパティpublic Surname LastName
はセッター検証を行いません。また、Surname
再利用可能です。
Surname
私の例ではは再利用可能なため、プロパティセッターの検証をコード内の他の場所にコピー/貼り付けるときに心配する必要はありません。姓のビジネスルールに変更を加えた場合でも、姓の検証が複数の場所にあるかどうかも疑問に思いません。Value Objectsについて投稿したリンクをチェックする
オブジェクト指向プログラミングの原則によると、クラスの内部動作は外部の世界から隠されるべきです。フィールドを公開すると、本質的にはクラスの内部実装が公開されます。したがって、フィールドをプロパティ(またはJavaの場合はメソッド)でラップして、コードを壊さずに実装を変更できるようにします。プロパティにロジックを配置できるので、必要に応じて検証ロジックなどを実行できます。C#3には、自動プロパティのわかりにくい概念があります。これにより、プロパティを定義するだけで済み、C#3コンパイラはプライベートフィールドを生成します。
public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Age{get;set;} //AutoProperty generates private field for us
}
public int myVar { get; set; }
実際には何を表しているのかを理解するのがかなり難しい場合があります(それが理由だと思います)少なくとも50%のヒットがこの質問で取得されます)。
virtual
それ自体がオブジェクト指向プログラミングの一部です。
virtual
それ自体はOOP とは呼びません。これは、ポリモーフィズムを可能にするツールであり、OOPを有効にする主要なツールの1つです。ただし、それ自体はOOPではなく、公開の自動プロパティについて本質的にOOPはありません。リフレクションやOOP関連のデータバインディングなども考慮しません。通常、私はそれについてそれほど面倒ではありませんが、答えはコード例の背後にある原動力としてOOの原則を具体的に言及しており、私はそれに同意しません。
ギアを回転させる可能性のあるプロパティの使用例をいくつか紹介します。
プロパティを使用すると、プロパティの値が変更されたとき(別名PropertyChangedEvent)、またはキャンセルをサポートするために値が変更される前に、イベントを発生させることができます。
これは(直接アクセス)フィールドでは不可能です。
public class Person {
private string _name;
public event EventHandler NameChanging;
public event EventHandler NameChanged;
public string Name{
get
{
return _name;
}
set
{
OnNameChanging();
_name = value;
OnNameChanged();
}
}
private void OnNameChanging(){
NameChanging?.Invoke(this,EventArgs.Empty);
}
private void OnNameChanged(){
NameChanged?.Invoke(this,EventArgs.Empty);
}
}
それらの多くは、技術の長所と短所を説明してきたProperties
し、Field
それがリアルタイム例に取得する時間です。
1.プロパティにより、読み取り専用アクセスレベルを設定できます
ケースを考えてみましょうdataTable.Rows.Count
とdataTable.Columns[i].Caption
。彼らはクラスから来て、DataTable
両方とも私たちに公開されています。それらに対するアクセスレベルの違いは、値をに設定することはできませんdataTable.Rows.Count
が、への読み取りと書き込みは可能dataTable.Columns[i].Caption
です。それは可能Field
ですか?番号!!!これはProperties
のみで行うことができます。
public class DataTable
{
public class Rows
{
private string _count;
// This Count will be accessable to us but have used only "get" ie, readonly
public int Count
{
get
{
return _count;
}
}
}
public class Columns
{
private string _caption;
// Used both "get" and "set" ie, readable and writable
public string Caption
{
get
{
return _caption;
}
set
{
_caption = value;
}
}
}
}
2. PropertyGridのプロパティ
Button
Visual Studioで作業した可能性があります。そのプロパティは「いいPropertyGrid
ねText
」Name
などで表示されます。ボタンをドラッグアンドドロップすると、プロパティをクリックするButton
と、クラスとフィルターが自動的に検出されてProperties
表示されますPropertyGrid
(パブリックであってもPropertyGrid
表示されませんField
)。
public class Button
{
private string _text;
private string _name;
private string _someProperty;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
[Browsable(false)]
public string SomeProperty
{
get
{
return _someProperty;
}
set
{
_someProperty= value;
}
}
ではPropertyGrid
、プロパティName
とText
が表示されますが、は表示されませんSomeProperty
。なぜ???プロパティは属性を受け入れることができるからです。[Browsable(false)]
がfalseの場合は表示されません。
3.プロパティ内でステートメントを実行できます
public class Rows
{
private string _count;
public int Count
{
get
{
return CalculateNoOfRows();
}
}
public int CalculateNoOfRows()
{
// Calculation here and finally set the value to _count
return _count;
}
}
4.バインディングソースで使用できるのはプロパティのみです
ソースのバインドは、コードの行数を減らすのに役立ちます。Fields
は受け入れませんBindingSource
。そのために使用する必要がありますProperties
。
5.デバッグモード
Field
値の保持に使用していると考えてください。ある時点で、そのフィールドの値がnullになる場所をデバッグして確認する必要があります。コードの行数が1000を超える場所で行うのは困難です。このような状況ではProperty
、内でデバッグモードを使用および設定できますProperty
。
public string Name
{
// Can set debug mode inside get or set
get
{
return _name;
}
set
{
_name = value;
}
}
フィールドは、クラスまたは構造体で直接宣言された変数です。クラスまたは構造体は、インスタンスフィールドまたは静的フィールド、あるいはその両方を持つことができます。通常、フィールドは、プライベートまたは保護されたアクセシビリティを持つ変数に対してのみ使用する必要があります。クラスがクライアントコードに公開するデータは、メソッド、プロパティ、インデクサーを通じて提供する必要があります。これらの構成体を使用して内部フィールドに間接的にアクセスすることにより、無効な入力値を防ぐことができます。
プロパティは、読み取り、書き込み、またはプライベートフィールドの値を計算するための柔軟なメカニズムを提供する部材です。プロパティは、パブリックデータメンバーのように使用できますが、実際にはアクセサーと呼ばれる特別なメソッドです。これにより、データへのアクセスが容易になり、メソッドの安全性と柔軟性が向上します。プロパティを使用すると、実装や検証コードを隠しながら、クラスが値を取得および設定するパブリックな方法を公開できます。getプロパティアクセサーはプロパティ値を返すために使用され、setアクセサーは新しい値を割り当てるために使用されます。
プロパティには、オブジェクトのパブリックインターフェイスを壊すことなく、オブジェクトのデータへのアクセス方法を変更できるという主な利点があります。たとえば、追加の検証を追加する必要がある場合、または格納されたフィールドを計算済みフィールドに変更する必要がある場合、最初にフィールドをプロパティとして公開しておけば簡単に行うことができます。フィールドを直接公開した場合は、クラスのパブリックインターフェイスを変更して新しい機能を追加する必要があります。その変更は既存のクライアントを破壊し、新しいバージョンのコードを使用する前に再コンパイルする必要があります。
何百万人ものユーザーが使用する.NET Frameworkのように、広く利用できるように設計されたクラスライブラリを作成すると、問題が発生する可能性があります。ただし、小さなコードベース内で内部的に使用されるクラス(たとえば、50 K行以下)を記述している場合、変更によって悪影響を受けることはないため、それほど大きな問題ではありません。その場合、それは本当に個人的な好みに帰着します。
プロパティは非対称アクセスをサポートします。つまり、ゲッターとセッターのいずれか、または2つのうちの1つだけを持つことができます。同様に、プロパティはゲッター/セッターの個々のアクセシビリティをサポートします。フィールドは常に対称です。つまり、常に値を取得および設定できます。これの例外は、初期化後に明らかに設定できない読み取り専用フィールドです。
プロパティは非常に長い時間実行され、副作用があり、例外をスローすることさえあります。フィールドは高速で、副作用はなく、例外をスローすることはありません。副作用のため、プロパティは呼び出しごとに異なる値を返す場合があります(DateTime.Nowの場合と同様に、DateTime.Nowが常にDateTime.Nowと等しいとは限りません)。フィールドは常に同じ値を返します。
フィールドはout / refパラメータに使用できますが、プロパティは使用できません。プロパティは追加のロジックをサポートしています。これは、とりわけ遅延読み込みを実装するために使用できます。
プロパティは、値を取得/設定することを意味するものをカプセル化することにより、抽象化のレベルをサポートします。
ほとんどの場合/すべての場合にプロパティを使用しますが、副作用を回避するようにしてください。
バックグラウンドでは、プロパティはメソッドにコンパイルされます。したがって、Name
プロパティはget_Name()
およびにコンパイルされset_Name(string value)
ます。これは、コンパイルされたコードを調べるとわかります。そのため、これらを使用すると、(非常に)小さなパフォーマンスオーバーヘッドが発生します。通常、フィールドを外部に公開する場合は常にプロパティを使用し、値の検証を行う必要がある場合はプロパティを内部で使用することがよくあります。
プライベート変数(フィールド)を他のクラスからクラスのオブジェクトにアクセスできるようにするには、それらの変数のプロパティを作成する必要があります。
たとえば、「id」および「name」という名前の変数がプライベートであるが、この変数がクラス外での読み取り/書き込み操作に必要な場合があります。その状況では、プロパティは、プロパティに定義されたget / setに応じて、その変数を読み取り/書き込みできるようにするのに役立ちます。プロパティは、読み取り専用/書き込み専用/読み取り/書き込みの両方にすることができます。
ここにデモがあります
class Employee
{
// Private Fields for Employee
private int id;
private string name;
//Property for id variable/field
public int EmployeeId
{
get
{
return id;
}
set
{
id = value;
}
}
//Property for name variable/field
public string EmployeeName
{
get
{
return name;
}
set
{
name = value;
}
}
}
class MyMain
{
public static void Main(string [] args)
{
Employee aEmployee = new Employee();
aEmployee.EmployeeId = 101;
aEmployee.EmployeeName = "Sundaran S";
}
}
ここの2番目の質問「プロパティの代わりにフィールドを使用する必要があるのはいつですか?」は、 、この他の答えとちょっとあまりにもこの1ではなく、本当に多くのディテール。
一般に、他のすべての答えは、優れた設計に関するスポットオンです。フィールドを公開するよりもプロパティを公開することを優先します。あなたはおそらくしませんが、定期的に自分で言って見つけるそれはだ、「うわー、私が代わりにプロパティのこのフィールドを作っていた場合でしょうかずっと悪い事を想像」そんなに、あなたはすごい」と言うだろうな状況を考えると、より珍しいです神様に感謝します。ここではプロパティの代わりにフィールドを使用しました。」
ただし、フィールドにはプロパティよりも優れている点が1つあります。それは、「ref」/「out」パラメーターとして使用できることです。次のシグネチャを持つメソッドがあるとします。
public void TransformPoint(ref double x, ref double y);
そのメソッドを使用して、次のように作成された配列を変換するとします。
System.Windows.Point[] points = new Point[1000000];
Initialize(points);
XとYなので、これを行うには最速の方法だと思いますはプロパティます。
for (int i = 0; i < points.Length; i++)
{
double x = points[i].X;
double y = points[i].Y;
TransformPoint(ref x, ref y);
points[i].X = x;
points[i].Y = y;
}
そして、それはかなり良いことになるでしょう!他に証明できる測定値がない限り、悪臭を放つ理由はありません。しかし、技術的にこれほど高速であるとは保証されていません。
internal struct MyPoint
{
internal double X;
internal double Y;
}
// ...
MyPoint[] points = new MyPoint[1000000];
Initialize(points);
// ...
for (int i = 0; i < points.Length; i++)
{
TransformPoint(ref points[i].X, ref points[i].Y);
}
いくつかやって 自分で測定をと、フィールドを含むバージョンは、プロパティを含むバージョン(.NET 4.6、Windows 7、x64、リリースモード、デバッガーが接続されていないバージョン)と比べて約61%の時間を要します。TransformPoint
メソッドが高価になるほど、違いがはっきりしなくなります。これを自分で繰り返すには、最初の行をコメントアウトして実行し、コメントアウトしないで実行します。
上記のパフォーマンス上の利点がなかったとしても、InterlockedまたはVolatileファミリのメソッドを呼び出す場合など、refおよびoutパラメータを使用できることが有益である他の場所があります。 注:これが初めての場合、Volatileは基本的に、volatile
キーワードです。そのため、のようにvolatile
、その名前が示すとおり、すべてのスレッドセーフティの問題を魔法のように解決するわけではありません。
「ああ、私はプロパティの代わりにフィールドを公開し始めるべきだ」と言っているように私が絶対に思われたくない。重要なのは、「ref」または「out」パラメーターを取る呼び出しでこれらのメンバーを定期的に使用する必要がある場合、特に、プロパティの値が追加された要素が必要になる可能性が低い単純な値型である可能性がある場合です。議論をすることができます。
フィールドとプロパティは互いに似ているように見えますが、2つの完全に異なる言語要素です。
フィールドは、クラスレベルでデータを格納する唯一のメカニズムです。フィールドは、概念的にはクラススコープの変数です。クラス(オブジェクト)のインスタンスにデータを格納する場合は、フィールドを使用する必要があります。他に選択肢はありません。プロパティはデータを格納できませんが、格納できるように見える場合があります。下記をご覧ください。
一方、プロパティはデータを格納しません。これらはメソッドのペア(getとset)であり、構文的にはフィールドと同じように呼び出すことができ、ほとんどの場合、フィールドにアクセス(読み取りまたは書き込み)するため、混乱が生じます。ただし、プロパティメソッドは(固定プロトタイプのようないくつかの制限があります)通常のC#メソッドであるため、通常のメソッドと同じように実行できます。つまり、1000行のコードを持つことができ、例外をスローしたり、別のメソッドを呼び出したり、仮想、抽象、またはオーバーライドすることもできます。プロパティが特別なのは、C#コンパイラが、特定のプロパティ(広く使用されている機能)を検索するために使用できる追加のメタデータをアセンブリに格納することです。
プロパティメソッドの取得と設定には、次のプロトタイプがあります。
PROPERTY_TYPE get();
void set(PROPERTY_TYPE value);
つまり、フィールドと2つの対応するメソッドを定義することで、プロパティを「エミュレート」できるということです。
class PropertyEmulation
{
private string MSomeValue;
public string GetSomeValue()
{
return(MSomeValue);
}
public void SetSomeValue(string value)
{
MSomeValue=value;
}
}
このようなプロパティエミュレーションは、標準のC ++のように、プロパティをサポートしないプログラミング言語では一般的です。C#では、フィールドへのアクセス方法として常にプロパティを優先する必要があります。
フィールドだけがデータを格納できるため、より多くのフィールドクラスが含まれ、そのようなクラスのより多くのメモリオブジェクトが消費します。一方、クラスに新しいプロパティを追加しても、そのようなクラスのオブジェクトは大きくなりません。以下がその例です。
class OneHundredFields
{
public int Field1;
public int Field2;
...
public int Field100;
}
OneHundredFields Instance=new OneHundredFields() // Variable 'Instance' consumes 100*sizeof(int) bytes of memory.
class OneHundredProperties
{
public int Property1
{
get
{
return(1000);
}
set
{
// Empty.
}
}
public int Property2
{
get
{
return(1000);
}
set
{
// Empty.
}
}
...
public int Property100
{
get
{
return(1000);
}
set
{
// Empty.
}
}
}
OneHundredProperties Instance=new OneHundredProperties() // !!!!! Variable 'Instance' consumes 0 bytes of memory. (In fact a some bytes are consumed becasue every object contais some auxiliarity data, but size doesn't depend on number of properties).
プロパティメソッドは何でも実行できますが、ほとんどの場合、オブジェクトのフィールドにアクセスする方法として機能します。フィールドを他のクラスからアクセス可能にする場合は、2つの方法で行うことができます。
以下はpublicフィールドを使用するクラスです。
class Name
{
public string FullName;
public int YearOfBirth;
public int Age;
}
Name name=new Name();
name.FullName="Tim Anderson";
name.YearOfBirth=1979;
name.Age=40;
コードは完全に有効ですが、設計の観点からは、いくつかの欠点があります。フィールドは読み取りと書き込みの両方が可能なため、ユーザーがフィールドに書き込むことを防ぐことはできません。readonly
キーワードを適用できますが、この方法では、コンストラクターでのみ読み取り専用フィールドを初期化する必要があります。さらに、無効な値をフィールドに格納することを妨げるものは何もありません。
name.FullName=null;
name.YearOfBirth=2200;
name.Age=-140;
コードは有効です。それらは非論理的ですが、すべての割り当てが実行されます。Age
負の値があり、YearOfBirth
遠い将来であり、年齢に対応せず、FullName
nullです。フィールドを使用するとclass Name
、ユーザーがそのような間違いを犯すのを防ぐことはできません。
これらの問題を修正するプロパティを含むコードを次に示します。
class Name
{
private string MFullName="";
private int MYearOfBirth;
public string FullName
{
get
{
return(MFullName);
}
set
{
if (value==null)
{
throw(new InvalidOperationException("Error !"));
}
MFullName=value;
}
}
public int YearOfBirth
{
get
{
return(MYearOfBirth);
}
set
{
if (MYearOfBirth<1900 || MYearOfBirth>DateTime.Now.Year)
{
throw(new InvalidOperationException("Error !"));
}
MYearOfBirth=value;
}
}
public int Age
{
get
{
return(DateTime.Now.Year-MYearOfBirth);
}
}
public string FullNameInUppercase
{
get
{
return(MFullName.ToUpper());
}
}
}
クラスの更新バージョンには、次の利点があります。
FullName
そして、YearOfBirth
無効な値がチェックされています。Age
書き込み不可です。それはYearOfBirth
、現在の年ます。FullNameInUppercase
変換さFullName
れます。これは、プロパティの使用法の少し不自然な例です。プロパティは、通常、フィールド値をユーザーにより適した形式で表示するために使用されます-たとえば、特定の数値の数値で現在のロケールを使用しDateTime
ます。これに加えて、プロパティは仮想またはオーバーライドとして定義できます。これは、それらが通常の.NETメソッドであるためです。このようなプロパティメソッドには、通常のメソッドと同じルールが適用されます。
C#は、プロパティメソッドにインデックスパラメーターを持つプロパティであるインデクサーもサポートしています。以下がその例です。
class MyList
{
private string[] MBuffer;
public MyList()
{
MBuffer=new string[100];
}
public string this[int Index]
{
get
{
return(MBuffer[Index]);
}
set
{
MBuffer[Index]=value;
}
}
}
MyList List=new MyList();
List[10]="ABC";
Console.WriteLine(List[10]);
C#3.0以降では、自動プロパティを定義できます。以下がその例です。
class AutoProps
{
public int Value1
{
get;
set;
}
public int Value2
{
get;
set;
}
}
class AutoProps
プロパティのみを含んでいても(またはそのように見えます)、2つの値を格納でき、このクラスのオブジェクトのサイズはsizeof(Value1)+sizeof(Value2)
= 4 + 4 = 8バイトです。
この理由は簡単です。自動プロパティを定義すると、C#コンパイラは非表示フィールドと、この非表示フィールドにアクセスするプロパティメソッドを持つプロパティを含む自動コードを生成します。これがコンパイラが生成するコードです。
以下は、コンパイルされたアセンブリからILSpyによって生成されたコードです。クラスには、生成された非表示フィールドとプロパティが含まれています。
internal class AutoProps
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int <Value1>k__BackingField;
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int <Value2>k__BackingField;
public int Value1
{
[CompilerGenerated]
get
{
return <Value1>k__BackingField;
}
[CompilerGenerated]
set
{
<Value1>k__BackingField = value;
}
}
public int Value2
{
[CompilerGenerated]
get
{
return <Value2>k__BackingField;
}
[CompilerGenerated]
set
{
<Value2>k__BackingField = value;
}
}
}
したがって、ご覧のように、コンパイラはフィールドを使用して値を格納します。フィールドがオブジェクトに値を格納する唯一の方法であるためです。
ご覧のとおり、プロパティとフィールドの使用構文は似ていますが、概念は大きく異なります。自動プロパティまたはイベントを使用する場合でも、非表示フィールドは、実際のデータが格納されるコンパイラーによって生成されます。
フィールド値を外部からアクセスできるようにする必要がある場合(クラスのユーザー)は、パブリックフィールドまたは保護フィールドを使用しないでください。フィールドは常にプライベートとしてマークする必要があります。プロパティを使用すると、値のチェック、書式設定、変換などを行うことができ、一般的にコードをより安全で読みやすく、将来の変更のために拡張することができます。
スレッドプリミティブを使用する場合は、フィールドを使用する必要があります。プロパティはスレッド化されたコードを壊す可能性があります。それとは別に、コーリーが言ったことは正しいです。
(これは本当にコメントであるべきですが、コメントを投稿することはできません。投稿として適切でない場合は失礼します)。
私はかつて、次のように、同等のプロパティdefがフィールドにアクセスするだけの場合に、プロパティではなくパブリックフィールドを使用することが推奨されている場所で働いていました。
get { return _afield; }
set { _afield = value; }
彼らの推論は、必要に応じてパブリックフィールドを後でプロパティに変換できる可能性があるというものでした。当時は少し奇妙に思えました。これらの投稿から判断すると、ここではあまり同意しないようです。物事を変えようとするために何を言いましたか?
編集:この場所のすべてのコードベースが同時にコンパイルされたことを追加する必要があります。そのため、(パブリックフィールドをプロパティに変更して)クラスのパブリックインターフェイスを変更することは問題ではないと考えているかもしれません。
技術的には、プロパティはユーザーが作成したフィールド、またはコンパイラが自動的に作成したフィールドのラッパーにすぎないため、違いはないと思います。プロパティの目的は、カプセル化を強制し、軽量なメソッドのような機能を提供することです。フィールドをパブリックとして宣言するのは単に悪い習慣ですが、問題はありません。
プロパティはフィールドをカプセル化するため、設定または取得する値に対して追加の処理を実行できます。フィールド値に対して前処理または後処理を行わない場合は、通常、プロパティを使用するのはやり過ぎです。
「車」というクラスがある場合。プロパティは、色、形状です。
フィールドはクラスのスコープ内で定義される変数です。
ウィキペディアから- オブジェクト指向プログラミング:
オブジェクト指向プログラミング(OOP)は、「オブジェクト」の概念に基づいたプログラミングパラダイムです。これは、属性と呼ばれるフィールドの形でデータを含むデータ構造です。そしてコードは、手順の形で、しばしば方法として知られています。(強調を追加)
プロパティは、実際にはオブジェクトの動作の一部ですが、オブジェクトのコンシューマーに、オブジェクトのデータを操作するような錯覚/抽象化を提供するように設計されています。
フィールドの私の設計は、フィールドはその親、つまりクラスによってのみ変更する必要があるということです。結果、変数がプライベートになり、外部のクラス/メソッドを読み取る権限を与えることができるように、Getのみでプロパティのシステムを通過します。次に、フィールドはプロパティによって取得され、読み取り専用になります。それを変更したい場合は、メソッド(たとえば、コンストラクター)を実行する必要があります。この方法でセキュリティを確保すると、「フランジ」するため、コードをより適切に制御できるようになります。すべてを常に公開することができるので、可能性のあるすべてのケース、変数/メソッド/クラスなどの概念は...私の意見では、コードの開発、保守の助けにすぎません。たとえば、人がパブリックフィールドでコードを再開した場合、彼は何でもできるため、「非論理的」なことを行うことができます。目的に関連して、コードが書かれた理由のロジック。私の意見です。
クラシックモデルのプライベートフィールド/パブリックの読み取り専用プロパティを使用する場合、10個のプライベートフィールドに対して、10個のパブリックプロパティを記述します。コードは本当に大きくなる可能性があります。私はプライベートセッターを発見し、プライベートセッターでのみパブリックプロパティを使用します。セッターはプライベートフィールドをバックグラウンドで作成します。
それが私の昔の古典的なプログラミングスタイルでした:
public class MyClass
{
private int _id;
public int ID { get { return _id; } }
public MyClass(int id)
{
_id = id;
}
}
私の新しいプログラミングスタイル:
public class MyClass
{
public int ID { get; private set; }
public MyClass(int id)
{
ID = id;
}
}
考えてみてください。あなたはこの部屋に入る部屋とドアを持っています。誰が入ってくるかをチェックして部屋を確保したい場合は、プロパティを使用する必要があります。そうしないと、プロパティがドアにはならず、誰もが規制なしで簡単に入ることができます。
class Room {
public string sectionOne;
public string sectionTwo;
}
Room r = new Room();
r.sectionOne = "enter";
人々はsectionOneにかなり簡単に入り始めました、チェックはありませんでした
class Room
{
private string sectionOne;
private string sectionTwo;
public string SectionOne
{
get
{
return sectionOne;
}
set
{
sectionOne = Check(value);
}
}
}
Room r = new Room();
r.SectionOne = "enter";
今、あなたは人をチェックして、彼が彼と一緒に何か悪いことをしているかどうか知っています
フィールドはクラスの変数です。フィールドは、アクセス修飾子を使用してカプセル化できるデータです。
プロパティは、オブジェクトに関連付けられた状態とデータを定義するという点でフィールドに似ています。
フィールドとは異なり、プロパティには、ユーザーがデータを読み取ったり、データを書き込んだりする方法を制御する特別な構文があります。これらは、取得および設定演算子として知られています。多くの場合、設定ロジックは検証を行うために使用できます。
プロパティは、特別な種類のクラスメンバーです。プロパティでは、事前定義されたSetメソッドまたはGetメソッドを使用します。これらは、プライベートフィールドの値を読み取り、書き込み、または変更できるアクセサーを使用します。
たとえばEmployee
、名前、年齢、およびEmployee_Idのプライベートフィールドを持つという名前のクラスを考えてみましょう。クラスの外部からこれらのフィールドにアクセスすることはできませんが、プロパティを通じてこれらのプライベートフィールドにアクセスすることはできます。
なぜプロパティを使用するのですか?
クラスフィールドを公開して公開するのは危険です。割り当てられて返されるものを制御できないためです。
例でこれを明確に理解するために、ID、パスマーク、名前を持つ学生のクラスを例にとってみましょう。この例では、パブリックフィールドに関するいくつかの問題
この問題を取り除くにはGetメソッドとsetメソッドを使用します。
// A simple example
public class student
{
public int ID;
public int passmark;
public string name;
}
public class Program
{
public static void Main(string[] args)
{
student s1 = new student();
s1.ID = -101; // here ID can't be -ve
s1.Name = null ; // here Name can't be null
}
}
次に、getおよびsetメソッドの例を取り上げます。
public class student
{
private int _ID;
private int _passmark;
private string_name ;
// for id property
public void SetID(int ID)
{
if(ID<=0)
{
throw new exception("student ID should be greater then 0");
}
this._ID = ID;
}
public int getID()
{
return_ID;
}
}
public class programme
{
public static void main()
{
student s1 = new student ();
s1.SetID(101);
}
// Like this we also can use for Name property
public void SetName(string Name)
{
if(string.IsNullOrEmpty(Name))
{
throw new exeception("name can not be null");
}
this._Name = Name;
}
public string GetName()
{
if( string.IsNullOrEmpty(This.Name))
{
return "No Name";
}
else
{
return this._name;
}
}
// Like this we also can use for Passmark property
public int Getpassmark()
{
return this._passmark;
}
}
追加情報:デフォルトでは、getおよびsetアクセサーは、プロパティ自体と同じようにアクセスできます。より制限されたアクセス修飾子を適用することにより、(getおよびsetのために)個別にアクセサーのアクセシビリティを制御/制限できます。
例:
public string Name
{
get
{
return name;
}
protected set
{
name = value;
}
}
ここではgetはまだパブリックにアクセスされていますが(プロパティはpublicであるため)、setは保護されています(より制限されたアクセス指定子)。
プロパティはフィールドを公開するために使用されます。これらは、プライベートフィールドの値を読み取り、書き込み、または操作できるアクセサ(set、get)を使用します。
プロパティは、保存場所を指定しません。代わりに、値を読み取り、書き込み、または計算するアクセサーがあります。
プロパティを使用して、フィールドに設定されているデータのタイプに検証を設定できます。
たとえば、私たちにはプライベート整数フィールドの年齢があり、年齢は負にできないため、正の値を許可する必要があります。
ゲッターとセッターを使用する方法と、プロパティを使用する方法の2つがあります。
Using Getter and Setter
// field
private int _age;
// setter
public void set(int age){
if (age <=0)
throw new Exception();
this._age = age;
}
// getter
public int get (){
return this._age;
}
Now using property we can do the same thing. In the value is a key word
private int _age;
public int Age{
get{
return this._age;
}
set{
if (value <= 0)
throw new Exception()
}
}
自動実装プロパティ取得および設定アクセサにロジックがない場合は、自動実装プロパティを使用できます。
uがすると、自動実装プロパティのコンパイルをSEプライベート、匿名フィールド作成のみ取得し、セットアクセサーを介してアクセスすることができます。
public int Age{get;set;}
抽象プロパティ 抽象クラスには、派生クラスに実装する必要がある抽象プロパティがある場合があります。
public abstract class Person
{
public abstract string Name
{
get;
set;
}
public abstract int Age
{
get;
set;
}
}
// overriden something like this
// Declare a Name property of type string:
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
プロパティをプライベートに設定できますこれで、autoプロパティをプライベートに設定できます(クラスで設定)
public int MyProperty
{
get; private set;
}
このコードで同じことを達成できます。このプロパティでは、フィールドに値を直接設定する必要があるため、セット機能は使用できません。
private int myProperty;
public int MyProperty
{
get { return myProperty; }
}
ほとんどの場合、これは変数名(フィールド)ではなく、アクセスするプロパティ名になります。)では。その理由は、.NETおよびC#では特にクラス内のすべてのデータを保護する、クラスに関連付けられているため、インスタンス変数でも静的変数(クラス変数)でもかまいません。
アクセサの定義、設定、取得 を可能にする対応するプロパティでこれらの変数をすべて保護しますそれらのデータを操作するときに検証などを行うことができます。
しかし、Mathクラス(システム名前空間)などの他のケースでは、クラスに組み込まれている静的プロパティがいくつかあります。その1つは数学定数PIです。
例えば。Math.PI
また、PIは明確に定義されたデータであるため、PIの複数のコピーを用意する必要はなく、常に同じ値になります。したがって、静的変数は、クラスのオブジェクト間でデータを共有するために使用されることもありますが、データのコピーを1つだけ必要とする定数情報にも一般的に使用されます。