パブリック定数は「悪い」ですか?


38

これは:

public MyClass
{
    public const string SomeString = "SomeValue";
}

これより悪い:

public MyClass
{
    public static string SomeString { get{ return "SomeValue";}}
}

どちらも同じ方法で参照できます。

if (someString == MyClass.SomeString)
     ...

ただし、2番目はプロパティであるという保護があります。しかし、実際にはこれはconstよりもはるかに優れていますか?

私は、公共の場を持つことの危険を何度も学びました。したがって、パブリックフィールドでこれらの定数を使用するコードを見たとき、すぐにそれらをプロパティにリファクタリングし始めました。しかし、途中で、定数よりも静的なプロパティを使用することの利点について疑問に思いました。

何か案は?


1
この方法で使用されるパブリック定数は問題ありません。この方法でプロパティを使用するのはやり過ぎです。
バーナード

2
readonlyキーワードの使用を検討しましたか?ReadOnlyは、多くの投稿で言及された問題なしに、constのよりきれいな構文を提供します。
マットラッフェル

次のこともできます... public static readonly type constantName = 0;
スヌープ

回答:


56

C#では、このスレッドで言及されている理由がどれも非常に悪いです。

C#のパブリック定数は、参照アセンブリに組み込まれます。つまり、MyClassのSomeStringを参照する別のアセンブリにSomeOtherClassがある場合、SomeOtherClass用に生成されたCILにはハードコードされた「SomeValue」文字列が含まれます。

MyClassを含むがSomeOtherClassを含まないdllを再デプロイし、constを変更すると、SomeOtherClassには、元の値が含まれると思われるものは含まれません。

100%ポジティブなら、Piのような普遍的な定数です。それ以外の場合は慎重に踏んでください。

これはより良い説明です:https : //stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly


3
@Oded、ただしconst読み取り専用プロパティと同じ違いがあります。const呼び出しアセンブリにベイク処理されますが、読み取り専用プロパティはベイク処理されません。
-svick

1
これは私が知らなかったものです。パブリックフィールドが悪いことのさらなる証拠です。Piの「安全な」例でさえ悪い考えだと思います(開発者がPiの精度を多かれ少なかれ望んでいるときはどうですか?そして、この問題を知らずにアセンブリを変更します)。解決策であり、注意を怠ると、これが本当に痛烈です。
ヴァッカーノ

2
この「コピー」はC#の他の部分で発生しますか?(つまり列挙型)
ヴァッカーノ

2
はい、コピーは行われます。通常、これは問題ではありませんが、コードがEnumの数値を使用し、この質問で概説されている方法で変更された場合、問題が発生する可能性があります。
ヴァッカーノ

1
これはconst、C#が馬鹿げている主な理由の1つです。不変のサポートを改善する必要があります...
KChaloux

22

フィールドをプロパティに変更することは、重大な変更です。 バイナリ、ソース、およびリフレクションの互換性が失われます。

加えて:

  • プロパティを使用したよりきめ細かいアクセス制御があります。公に入手可能にする必要があるが、本当に保護されたアクセスでのみ設定したいですか?問題ありません(少なくともC#2以降)。
  • 値が変わるたびにデバッガーに侵入したいですか?セッターにブレークポイントを追加するだけです。
  • すべてのアクセスを記録しますか?ゲッターにログを追加するだけです。
  • プロパティはデータバインディングに使用されます。フィールドはそうではありません。

http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx

とはいえ、APIが定数でなくなるような方法で変更しない限り、定数が実際にどのように影響を受けるかはわかりません(特に上記の機能が必要ない場合)。


11

パブリックフィールドの危険は、それらが可変であり、それらの基礎となる実装が変更される可能性があるという事実にあります。

それがに来るときはconst、この通常(同じくパブリック列挙に)問題ではない-あなたがいることを考えていない限りconst変更可能なように終わると、あなたには、いくつかの時点でアクセサ周りのカプセル化を必要とすることでしょう(それが見られた回数ログインに言いますup)、あなたはそれを公開することもできますconst


1

定数はデータです。プロパティは、値を「見る」ほどの動作の可能性を意味します。

一定のデータを使用したバンドル動作(またはその将来の可能性)は、完全に間違っています。ほとんどのシステムでは、それは実際には重要ではありませんが、可能です。

値が「PI」であり、システムの計算で広く使用されているとしましょう。プロパティの背後に配置すると、クライアントプログラマーは防御的にプログラムする必要があります。重複する定数に値を割り当てる必要があります。重複しない場合、ライブラリの次のバージョンでは、プロパティの背後に不要な「動作」が導入される可能性があります。プロパティの動作(コンパイルされたライブラリにある場合)は不明です。テストではうまく機能するかもしれませんが、特別な条件が満たされた場合に実行される隠しコードが存在する可能性があります。これは時期尚早の最適化ではありません。特にリアルタイムシステムでは、人々の生活は依存しています。

クライアントプログラマーは、言語が重複する定数にプロパティ値を割り当てることを許可しないため、定数の安全性を失うことさえあります。

また、プログラマが自分の定数にプロパティ値を割り当てることを余儀なくされると、プロパティで達成したいと思っていた動作を事実上無効にします。

真の定数データは、カプセル化を必要としないか、必要としません。

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