C#でプロパティの使用を避ける必要があるのはなぜですか?


102

Jeffrey Richterは、優れた著書であるCLR Via C#で、プロパティは好きではないので、使用しないことを推奨しています。彼は何らかの理由を挙げましたが、私にはよくわかりません。プロパティを使用する理由または使用しない理由を誰かに説明できますか?自動プロパティを備えたC#3.0では、これは変更されますか?

参考として、ジェフリー・リヒターの意見を追加しました。

•プロパティは読み取り専用または書き込み専用です。フィールドアクセスは常に読み取りと書き込みが可能です。プロパティを定義する場合は、getとsetの両方のアクセサーメソッドを提供するのが最善です。

•プロパティメソッドは例外をスローする場合があります。フィールドアクセスは例外をスローしません。

•プロパティをoutまたはrefパラメーターとしてメソッドに渡すことはできません。フィールドはできます。たとえば、次のコードはコンパイルされません。

using System;
public sealed class SomeType
{
   private static String Name 
   {
     get { return null; }
     set {}
   }
   static void MethodWithOutParam(out String n) { n = null; }
   public static void Main()
   {
      // For the line of code below, the C# compiler emits the following:
      // error CS0206: A property or indexer may not
      // be passed as an out or ref parameter
      MethodWithOutParam(out Name);
   }
}

•プロパティメソッドの実行には時間がかかる場合があります。フィールドへのアクセスは常に即座に完了します。プロパティを使用する一般的な理由は、スレッドの同期を実行することです。これにより、スレッドが永久に停止する可能性があるため、スレッドの同期が必要な場合はプロパティを使用しないでください。そのような状況では、方法が推奨されます。また、クラスにリモートアクセスできる場合(たとえば、クラスがSystem.MashalByRefObjectから派生している場合)、プロパティメソッドの呼び出しは非常に遅くなるため、プロパティよりもメソッドの方が適しています。私の意見では、MarshalByRefObjectから派生したクラスではプロパティを使用しないでください。

•連続して複数回呼び出された場合、プロパティメソッドは毎回異なる値を返す場合があります。フィールドは毎回同じ値を返します。System.DateTimeクラスには、現在の日付と時刻を返す読み取り専用のNowプロパティがあります。このプロパティをクエリするたびに、異なる値が返されます。これは誤りであり、Microsoftは、Nowをプロパティではなくメソッドにすることでクラスを修正できることを願っています。

•プロパティメソッドは、観察可能な副作用を引き起こす可能性があります。フィールドアクセスは行いません。言い換えると、型のユーザーは、型で定義されたさまざまなプロパティを、型の異なる動作に気付かずに、選択した順序で設定できる必要があります。

•プロパティメソッドは追加のメモリを必要とする場合や、実際にはオブジェクトの状態の一部ではない何かへの参照を返す場合があるため、返されたオブジェクトを変更しても元のオブジェクトには影響しません。フィールドをクエリすると、常に元のオブジェクトの状態の一部であることが保証されているオブジェクトへの参照が返されます。コピーを返すプロパティでの作業は、開発者にとって非常に混乱する可能性があり、この特性は文書化されていないことがよくあります。


11
私は「CLRを介したCLR」の第3版を所有しており、242ページでリヒター氏は個人的にプロパティは好きではないが、使用しないことを勧めていません。これを読んだ本のバージョンとページ番号を引用してください。
kirk.burleson 2012

回答:


173

プロパティを嫌うジェフの理由は、フィールドのように見えるためです。そのため、違いを理解していない開発者は、実行が安価であると想定して、フィールドのように扱います。

個人的に私はこの特定の点で彼に同意しません-私はプロパティがクライアントコードを同等のメソッド呼び出しよりもはるかに読みやすくすることに気づきます。プロパティは基本的に変装したメソッドであることを開発者が知る必要があることに私は同意します。しかし、それについて開発者を教育することは、メソッドを使用してコードを読みにくくすることよりも優れていると思います。(特に、同じステートメントで複数のゲッターとセッターが呼び出されるJavaコードを見てきたので、同等のC#コードを読む方がはるかに簡単であることを知っています。デメテルの法則はすべて理論的には非常に優れていますが、foo.Name.Length実際には正しい使い方...)

(そして、いいえ、自動的に実装されたプロパティは実際にはこれを変更しません。)

これは、拡張メソッドの使用に対する反対の議論に少し似ています-私は推論を理解できますが、実用的な利点(控えめに使用した場合)は私の見解の欠点よりも重要です。


答えてくれてありがとう!拡張メソッドの使用に対する反対論について:あなたはいくつかのJeffrey Richterのトピックについて話しているのですか、それとも抽象的にですか?
abatishchev 2009年

@abatishchev:それは、拡張メソッドに関する単なる一般的なポイントでした。プロパティとは直接関係ありません。
Jon Skeet、

私はさらに行きます。パフォーマンスの側面を除いて、何かがフィールドやプロパティである場合にプログラマが知っておくべき理由はわかりません。彼はそれをオブジェクトインスタンスのSTATEを指定するインスタンスの属性と考えるべきであり、オブジェクト実装はその状態へのすべての変更(クラスのコントラクト内)を処理する必要があります。したがって、クラスの実装の再設計が行われた場合、プロパティは、場合によってはフィールドになることもあれば、フィールドになることもあります。次に、フィールドとプロパティのどちらを決定するかは、状態の一貫性を保つためにどれだけの保護が必要かという問題です。
TheBlastOne 2011

1
@PatrickFromberg:読み取り専用フィールドを使用する大量のコードを見逃しているようです。プロパティが変更可能性を意味することは言うまでもありません。私はよく読み取り専用プロパティをサポートする読み取り専用フィールドを持っています-それは悪いことだと思いますか?
Jon Skeet、2014

1
@Patrick:いいえ、APIを実装から分離するという利点があります。フィールドからプロパティを計算する方法を後で変更できます(たとえば、1つのフィールドから2つの関連するプロパティを計算するため)。
Jon Skeet

34

さて、彼の議論を一つずつ見てみましょう:

プロパティは読み取り専用または書き込み専用です。フィールドアクセスは常に読み取りと書き込みが可能です。

アクセスをよりきめ細かく制御できるため、これはプロパティにとって有利です。

プロパティメソッドは例外をスローする場合があります。フィールドアクセスは例外をスローしません。

これはほとんど当てはまりますが、初期化されていないオブジェクトフィールドでメソッドを呼び出すと、例外がスローされることがあります。

•プロパティをoutまたはrefパラメーターとしてメソッドに渡すことはできません。フィールドはできます。

フェア。

•プロパティメソッドの実行には時間がかかる場合があります。フィールドへのアクセスは常に即座に完了します。

また、非常に時間がかかりません。

•連続して複数回呼び出された場合、プロパティメソッドは毎回異なる値を返す場合があります。フィールドは毎回同じ値を返します。

違います。(おそらく別のスレッドによって)フィールドの値が変更されていないことをどのようにして知ることができますか?

System.DateTimeクラスには、現在の日付と時刻を返す読み取り専用のNowプロパティがあります。このプロパティをクエリするたびに、異なる値が返されます。これは誤りであり、Microsoftは、Nowをプロパティではなくメソッドにすることでクラスを修正できることを願っています。

それが間違いであるなら、それはマイナーなものです。

•プロパティメソッドは、観察可能な副作用を引き起こす可能性があります。フィールドアクセスは行いません。言い換えると、型のユーザーは、型で定義されたさまざまなプロパティを、型の異なる動作に気付かずに、選択した順序で設定できる必要があります。

フェア。

•プロパティメソッドは追加のメモリを必要とする場合や、実際にはオブジェクトの状態の一部ではない何かへの参照を返す場合があるため、返されたオブジェクトを変更しても元のオブジェクトには影響しません。フィールドをクエリすると、常に元のオブジェクトの状態の一部であることが保証されているオブジェクトへの参照が返されます。コピーを返すプロパティでの作業は、開発者にとって非常に混乱する可能性があり、この特性は文書化されていないことがよくあります。

抗議のほとんどは、Javaのゲッターとセッターにも言えます。実際には、このような問題が発生することはほとんどありませんでした。

問題のほとんどは、より良い構文強調表示(つまり、フィールドとプロパティを区別する)によって解決できると思います。これにより、プログラマは何を期待できるかを理解できます。


3
「構文の強調表示を改善することで問題を解決できます」:パブリックフィールドをどのくらいの頻度で使用しますか?プライベートフィールドは通常、異なるスタイルを持ってい_fieldます。または単に小文字でもかまいませんfield
Steven Jeuris

18

私はその本を読んだことがなく、理解できない部分を引用していないので、推測する必要があります。

一部の人々は、あなたのコードに驚くべきことをさせることができるので、プロパティを嫌います。

入力した場合 Foo.Bar、それを読んでいる人は通常、これがFooクラスのメンバーフィールドに単にアクセスしていることを期待します。これは、安価でほぼ無料の操作であり、確定的です。私は何度もそれを呼び出すことができ、毎回同じ結果を得ることができます。

代わりに、プロパティを使用すると、実際には関数呼び出しになる場合があります。無限ループの可能性があります。データベース接続を開く場合があります。アクセスするたびに異なる値を返す可能性があります。

これは、LinusがC ++を嫌う理由と似ています。あなたのコードは読者にとって意外に振る舞うことができます。彼は演算子のオーバーロードを嫌っa + bています。必ずしも単純な加算を意味するわけではありません。これは、C#プロパティと同様に、非常に複雑な操作を意味する場合があります。副作用があるかもしれません。それは何でもします。

正直なところ、これは弱い議論だと思います。どちらの言語もこのようなものでいっぱいです。(C#でも演算子のオーバーロードを避ける必要がありますか?結局、同じ引数をそこで使用できます)

プロパティは抽象化を可能にします。私たちは、できるふりその何かが通常のフィールドであり、それは一つであったかのようにそれを使用し、舞台裏で何が起こるのかを心配する必要はありません。

それは通常良いことだと考えられていますが、明らかにプログラマが意味のある抽象化を書くことに依存しています。プロパティフィールドのように動作するはずです。副作用が発生したり、高価な操作や安全でない操作を実行したりしてはなりません。それらをフィールドとして考えることができるようにしたい。

しかし、私はそれらを完璧とは言えない理由があります。他の関数への参照によって渡すことはできません。

フィールドはとして渡すことがrefでき、呼び出された関数がフィールドに直接アクセスできるようにします。関数はデリゲートとして渡すことができ、呼び出された関数が直接それにアクセスできるようにします。

プロパティ...できません。

それは最悪だ。

しかし、それはプロパティが悪である、または使用されるべきではないという意味ではありません。多くの目的で、それらは素晴らしいです。


3
私の主張は、それが最初のフィールドであると想定すべきではないということです-他のクラスからそれを呼び出す場合、非定数フィールドはプライベートであるため、とにかく非定数フィールドにアクセスするべきではありません。(お知らせする命名規則もあります。)
Jon Skeet

1
ええ、同意します。議論は、「この構文がフィールドにのみ使用されることに慣れているため、他のケースをカバーするように拡張するのは悪いこと」に要約されるようです。そして、明らかな答えは、「まあ、それなら他のケースをカバーすることに慣れれば、それは悪くはない」です。;)
2009年

.net言語が、クラスがrefパラメータとして公開プロパティを持つ標準的な手段を提供することを願っています。特別な属性Fooを持つフォームのメンバー(例void Foo<T>(ActionByRef<Point,T> proc, ref T param):)、およびコンパイラーをに変換thing.Foo.X+=someVar;Foo((ref Point it, ref int param)=>it.X += param, ref someVar);ます。ラムダは静的デリゲートであるため、クロージャーは必要ありません。オブジェクトのユーザーは、プロパティをサポートする保存場所をすべて本物のrefパラメーターとして使用できます(refパラメーターとして他のメソッドに渡すこともできます)。
スーパーキャット

ラムダを手動で書き出すと、見た目がひどく見えるソースコードが生成されますが、そのため、コンパイラーに変換を実行させると便利です。「ref-callback-by-ref」プロパティを公開するクラスのコードはかなり合理的です。コードは、呼び出し側で醜い(変換がない)だけです。
スーパーキャット'10年

プロパティはメンバーとして偽装された関数呼び出しであるため、クラスのパブリック関数を渡すことができるのと同じように、参照によって渡すことはできません。そうするつもりなら、いつでもパブリックメンバーを使用できます。プロパティはスマートメンバーであり、セットに渡された無効なデータに対して例外をスローできます。
Diceyus 2017年

17

2009年に戻って、このアドバイスは、「Who Moved My Cheese」品種の攻撃のようでした。今日、それはおかしなことに時代遅れになっています。

多くの回答がつまらないように見えるが、真正面からは触れていない非常に重要な点の1つは、これらのプロパティの「危険性」がフレームワーク設計の意図的な部分であることです。

はい、プロパティは次のことができます:

  • ゲッターとセッターに異なるアクセス修飾子を指定します。これはフィールドに勝る利点です。一般的なパターンは、パブリックゲッターと保護されたまたは内部のセッターを使用することです。これは、フィールドだけでは達成できない非常に便利な継承技術です。

  • 例外をスローします。これまでのところ、これは特にデータバインディングの概念を含むUIフレームワークを使用する場合に、検証の最も効果的な方法の1つであり続けています。フィールドを操作するときにオブジェクトを有効な状態に保つことは、はるかに困難です。

  • 実行に時間がかかります。ここでの有効な比較は、フィールドではなく、長い時間がかかるメソッドとの比較です。ある作者の個人的な好み以外に、「方法が好ましい」という記述の根拠は与えられていません。

  • 後続の実行時にゲッターから異なる値を返します。これはほとんどの美徳称賛ポイントに、このような近接で冗談のように思えるref/ outvalueフィールドの後のフィールドでパラメータをref/のout呼び出しはほとんど予測できないので、その前の値とは異なることが保証されており、。

    我々は、特定の(と実質的に学術)なし求心性カップリングのシングルスレッドアクセスの場合の話をしている場合、だかなりよく理解し、それが目に見える状態変化の副作用を持っているだけで、悪い不動産デザインだし、多分私の記憶であること色褪せますが、DateTime.Now毎回同じ値が使用されることを期待している人々の例を思い出すことはできません。少なくとも、仮説を立ててそれをひどく台無しにしてしまうようなことはありませんDateTime.Now()

  • 目に見える副作用を引き起こします-もちろん、そもそもプロパティが言語機能として発明された理由です。マイクロソフト独自のプロパティデザインガイドラインでは、セッターの順序は重要ではないことを示しています。そうしないと、一時的な結合を意味します。確かに、フィールドだけで一時的な結合を実現することはできませんが、それは、メソッドが実行されるまで、フィールドだけでは意味のある動作をまったく起こせないためだけです。

    プロパティアクセサは実際に助けることができる防ぐ例えば、クラスがある場合-何らかのアクションが取られる前に、有効な状態にオブジェクトを強制することにより、一時的なカップリングの特定の種類をStartDateし、EndDateその後、設定、EndDate前にStartDate強制することができStartDate、同様の背中を。これは、イベント駆動型ユーザーインターフェイスの明白な例を含む、マルチスレッド環境または非同期環境でも当てはまります。

プロパティが実行できるその他のこと、フィールドに含めることができないもの:

  • 遅延読み込み、初期化順エラーを防止する最も効果的な方法の1つ。
  • 変更通知は、MVVMアーキテクチャのほぼ全体的な基盤です。
  • 継承、たとえば抽象クラスTypeName派生クラスを定義すると、興味深いが、それでも一定のメタデータを提供できます。
  • 上記のおかげで、傍受
  • インデクサーは、これまでにCOM相互運用機能と必然的に発生する大量のItem(i)呼び出しを処理する必要があったすべての人にとって、素晴らしいものとして認識されます。
  • 仕事のPropertyDescriptorデザイナーを作成するためと一般的なXAMLフレームワークのために不可欠です。

リヒターは明らかに多作の作者であり、CLRとC#についてはよく知っていますが、彼が最初にこのアドバイスを書いたときのようです(それが彼の最新の改訂版にあるかどうかはわかりません-心から願っています)彼は古い習慣を手放したくなかっただけで、C#の規則(たとえば、C ++など)を受け入れるのに苦労していました。

つまり、彼の「有害と見なされるプロパティ」の引数は、基本的に1つのステートメントにまとめられますプロパティはフィールドのように見えますが、フィールドのようには機能しない可能性があります。そして声明の問題は、それが真実ではない、またはよくてもそれが非常に誤解を招くものであるということです。プロパティフィールドのように見えません -少なくとも、フィールドのように見えるはずではありません。

C#は2つの非常に強力なコーディング規則があり、他のCLR言語で共有されている同様の規則があります。FXCopを守らないと、FXCopが悲鳴を上げます。

  1. フィールドは常にプライベートであり、パブリックであってはなりません
  2. フィールドはcamelCaseで宣言する必要があります。プロパティはPascalCaseです。

したがって、Foo.Bar = 42プロパティアクセサとフィールドアクセサのどちらであるかについて、あいまいさはありません。これはプロパティアクセサーであり、他のメソッドと同じように扱う必要があります。処理が遅い場合や、例外がスローされる場合があります。それがAbstractionの性質です。完全に宣言するクラスの判断に応じて、どのように反応するかを決定します。クラスの設計者は最小の驚きの原則を適用する必要がありますが、呼び出し元は、それが缶に記載されていることを行うことを除いて、プロパティについて何も仮定しないでください。それは意図的です。

プロパティの代わりに、どこでもgetter / setterメソッドを使用できます。これはJavaのアプローチであり、当初から物議を醸しています。それがあなたのバッグであれば大丈夫ですが、それは私たちが.NETキャンプに参加する方法ではありません。少なくとも静的に型付けされたシステムの範囲内で、FowlerがSyntactic Noiseと呼んでいるものを回避しようとします。余分な括弧、余分なget/ setイボ、または余分なメソッドシグネチャは必要ありません。明快さを失うことなくそれらを回避できる場合はそうではありません。

何でも好きなことを言いますが、foo.Bar.Baz = quux.Answers[42]は常によりもずっと読みやすくなりますfoo.getBar().setBaz(quux.getAnswers().getItem(42))。そして、これを1日に数千行読んでいると、違いが生まれます。

(そして、上の段落に対するあなたの自然な反応が「読むのは難しいが、それを複数の行に分割するともっと簡単になるだろう」と言うことであるなら、私はあなたがポイントを完全に逃したと言ってすみません。)


11

一般的にプロパティを使用しない理由はわかりません。

C#3+の自動プロパティは、構文を少し単純化するだけです(シンタティックシュガー)。


その本の215〜216ページを読んでください。私はあなたがジェフリー・リヒターが誰であるか知っていると確信しています!
Quan Mai

私は(C#を介したCLR、第2版)を読みましたが、彼の立場に同意せず、実際の理由でプロパティを使用しないことを確認していません!
abatishchev 2009年

良い本ですが、今のところ著者には同意できません。
Konstantin Tarkus、

著者がプロパティを使用しないように勧めている場所はどこですか?p.215-217で何も見つかりませんでした
コンスタンティン

私は質問にジェフリーの意見を追加しました:)。215-216ページの印刷版でそれを見つけることができます:)
Quan Mai

9

それはただ一人の意見です。私はかなりの数のC#の本を読んだことがあり、「プロパティを使用しないでください」と言っている人を見たことはありません。

私は個人的に、プロパティはC#の最も優れた点の1つだと思います。彼らはあなたが好きなメカニズムを介して状態を公開することができます。何かが最初に使用されたときに遅延インスタンスを作成し、値の設定などの検証を行うことができます。それらを使用して書き込む場合、プロパティはより優れた構文であるセッターおよびゲッターと考えるだけです。

プロパティに関する警告については、いくつかあります。1つはおそらくプロパティの誤用であり、もう1つは微妙な場合があります。

まず、プロパティはメソッドのタイプです。クラスのほとんどのユーザーはプロパティがかなり軽量であることを期待するため、プロパティに複雑なロジックを配置すると驚くかもしれません。

例えば

public class WorkerUsingMethod
{
   // Explicitly obvious that calculation is being done here
   public int CalculateResult()
   { 
      return ExpensiveLongRunningCalculation();
   }
}

public class WorkerUsingProperty
{
   // Not at all obvious.  Looks like it may just be returning a cached result.
   public int Result
   {
       get { return ExpensiveLongRunningCalculation(); }
   }
}

これらのケースにメソッドを使用すると、区別するのに役立ちます。

次に、さらに重要なことに、デバッグ中にプロパティを評価すると、プロパティに副作用が生じる可能性があります。

次のようなプロパティがあるとします。

public int Result 
{ 
   get 
   { 
       m_numberQueries++; 
       return m_result; 
   } 
}

ここで、クエリが多すぎる場合に発生する例外があるとします。デバッグを開始し、デバッガーでプロパティをロールオーバーするとどうなるでしょうか。悪いこと。これは避けてください!プロパティを見ると、プログラムの状態が変化します。

これらは私が持っている唯一の警告です。プロパティの利点は問題をはるかに上回っていると思います。


6

その理由は、非常に具体的な文脈の中で与えられたに違いありません。これは通常、逆の方法です。プロパティを使用すると、クライアントに影響を与えずにクラスの動作を変更できる抽象化レベルが得られるため、プロパティを使用することをお勧めします...


クライアントとクラスプロパティ間の「契約」の重要性を暗黙的に強調するための+1。
TheBlastOne 2011

6

ジェフリー・リヒターの意見の詳細を選ぶのは仕方がない:

プロパティは読み取り専用または書き込み専用です。フィールドアクセスは常に読み取りと書き込みが可能です。

誤り:フィールドは読み取り専用としてマークできるため、オブジェクトのコンストラクターのみがフィールドに書き込むことができます。

プロパティメソッドは例外をスローする場合があります。フィールドアクセスは例外をスローしません。

誤り:クラスの実装により、フィールドのアクセス修飾子がパブリックからプライベートに変更される可能性があります。実行時にプライベートフィールドを読み取ろうとすると、常に例外が発生します。


5

私はジェフリー・リヒターに同意しませんが、なぜ彼が不動産が好きでないのか推測できます(私は彼の本を読んだことがありません)。

プロパティはメソッドと同じように(実装に関して)、クラスのユーザーとして、そのプロパティはパブリックフィールドのように「多かれ少なかれ」動作することを期待しています。例:

  • プロパティのゲッター/セッター内で行われる時間のかかる操作はありません
  • プロパティゲッターには副作用がありません(複数回呼び出しても結果は変わりません)。

残念ながら、そのように動作しないプロパティを見てきました。しかし、問題はプロパティ自体ではなく、それらを実装した人々です。ですから、教育が必要です。


1
クリーンな契約の重要性を強調しているため、+ 1。参照ごとに異なる値を定期的に返す一見読み取り専用のプロパティを持つことは、読み取り書き込みプロパティです。それは、それ自体の値ではなく、(直接的または間接的に)他のインスタンス変数に書き込みません。これは悪いスタイルではありませんが、文書化する必要があります(または契約の暗黙の一部です)。
TheBlastOne 2011

4

プロパティを使用しないことを検討する時期があります。それは.Net Compact Frameworkコードの記述です。CF JITコンパイラーは、デスクトップJITコンパイラーと同じ最適化を実行せず、単純なプロパティアクセサーを最適化しません。そのため、この場合、単純なプロパティを追加すると、パブリックフィールドの使用によるコードの膨張が発生します。通常、これは問題にはなりませんが、ほとんどの場合、Compact Frameworkの世界では、厳しいメモリ制約に直面しているため、このようなわずかな節約でもカウントされます。


4

それらの使用は避けてはなりませんが、他の貢献者からの理由により、資格と注意を払って使用する必要があります。

データベースのアウトプロセスコールを内部で開いて顧客リストを読み取る、Customersのようなプロパティを以前に見ました。クライアントコードには 'for(int i to Customers.Count)'があり、反復ごとに、および選択した顧客のアクセスのために、データベースへの個別の呼び出しを引き起こしていました。これは、プロパティを非常に軽量に保つという原則を示す悪質な例です。内部フィールドへのアクセス以上のものはめったにありません。

プロパティを使用する場合の1つの引数は、設定されている値を検証できることです。もう1つは、プロパティの値が、TotalValue =金額*数量のように、単一のフィールドではなく、派生値になる場合があることです。


3

個人的には、単純なget / setメソッドを作成するときにのみプロパティを使用します。複雑なデータ構造になると、私はそれから離れます。


3

引数は、プロパティはフィールドのように見えるために悪いと想定しますが、驚くべきアクションを実行できます。この仮定は、.NETプログラマの期待するアクションによって無効になります。

プロパティはフィールドのようには見えません。フィールドはプロパティのように見えます。

•プロパティメソッドは例外をスローする場合があります。フィールドアクセスは例外をスローしません。

したがって、フィールドは、例外をスローしないことが保証されているプロパティのようなものです。

•プロパティをoutまたはrefパラメーターとしてメソッドに渡すことはできません。フィールドはできます。

だから、フィールドは、プロパティのようなものですが、それは追加の機能がありますに渡すref/ outメソッドを受け入れます。

•プロパティメソッドの実行には時間がかかる場合があります。フィールドへのアクセスは常に即座に完了します。[...]

したがって、フィールドは高速なプロパティのようなものです。

•連続して複数回呼び出された場合、プロパティメソッドは毎回異なる値を返す場合があります。フィールドは毎回同じ値を返します。System.DateTimeクラスには、現在の日付と時刻を返す読み取り専用のNowプロパティがあります。

したがって、フィールドは、フィールドが異なる値に設定されていない限り、同じ値を返すことが保証されているプロパティのようなものです。

•プロパティメソッドは、観察可能な副作用を引き起こす可能性があります。フィールドアクセスは行いません。

繰り返しますが、フィールドはそうしないことが保証されているプロパティです。

•プロパティメソッドは追加のメモリを必要とする場合や、実際にはオブジェクトの状態の一部ではない何かへの参照を返す場合があるため、返されたオブジェクトを変更しても元のオブジェクトには影響しません。フィールドをクエリすると、常に元のオブジェクトの状態の一部であることが保証されているオブジェクトへの参照が返されます。コピーを返すプロパティでの作業は、開発者にとって非常に混乱する可能性があり、この特性は文書化されていないことがよくあります。

これは驚くべきことかもしれませんが、これを行うプロパティだからではありません。むしろ、プロパティで変更可能なコピーを返す人はほとんどいないため、0.1%の場合は驚くべきことです。


0

プロパティの代わりにメソッドを呼び出すと、呼び出すコードの可読性が大幅に低下します。たとえばJ#では、Javaがプロパティとインデクサー(基本的には引数を持つプロパティ)をサポートしていないため、ADO.NETの使用は悪夢でした。結果のコードは非常に醜く、空の括弧メソッド呼び出しがいたるところにありました。

プロパティとインデクサーのサポートは、Javaに対するC#の基本的な利点の1つです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.