すべてのerrorMessageを配置できるリストを含むErrorMessagesクラスを作成することを計画していました。無効な入力が与えられるたびに、新しいメッセージがerrorMessagesリストに追加されます。したがって、ユーザーが「作成」ボタンをクリックすると、リスト内のすべてのメッセージが表示されます。これは物事を処理する良い方法ですか?
主観的には、ユーザーが入力した値が無効であるというフィードバックを即座に提供する方がよいと思います。そうすれば、彼らはすぐに戻ってそれを修正することができます。
つまり、考えてみてください。あなたが提案するアプローチは、文字通り彼らに問題の巨大なリストを与えるでしょう、それはあまりユーザーフレンドリーではありません。さらに、それらの問題をすべて覚えて、一度に1つずつ戻って修正できるようにするにはどうすればよいでしょうか。(ヒント:そうではありません。)
代わりに、ErrorProvider
クラスを使用して、適切なコントロールのすぐ横にエラーを表示することをお勧めします。私はこことここで私の答えの中でこのアプローチについてもう少し話しました。
もちろん、最終的な送信([OK] / [送信]ボタンをクリック)時にすべての入力が有効であることを確認する必要がありますが、それはエラーの有無を確認する単純なケースです。
Formクラスでこれを簡単に行うことができます。しかし、設定されたプロパティの入力を検証するためのいくつかのベストプラクティスの方法を覚えています。
はい、ここでのアイデアはカプセル化です。Formクラスは、フォームに関することだけを知っている必要があります。さまざまなコントロールすべてに対して、どのような種類の入力が有効であるか、または無効であるかを知る必要はありません。
代わりに、この検証ロジックは、データを格納するクラスなど、他の場所に配置する必要があります。そのクラスは、データを取得および設定するためのパブリックプロパティを公開し、setterメソッド内でデータを検証します。
つまり、Formが実行する必要があるのは、データクラスのsetterメソッドを呼び出すことだけです。データクラスはそのすべてを処理するため、フォームはデータの検証方法やデータの意味について何も知る必要はありません。
これは発生しないはずです。入力が有効でない限り、クラスのインスタンスを作成することはできません。
これが実際に当てはまる場合は、必要なすべてのデータをパラメーターとして受け入れるクラスのコンストラクターを提供する必要があります。コンストラクターの本体は、指定されたデータを検証し、いずれかが無効な場合は例外をスローします。例外はクラスの作成を防ぎ、無効なデータを含むクラスのインスタンスが存在しないようにします。
このようなクラスには、おそらくsetterメソッドはまったくなく、getterのみが含まれます。
ただし、これはC#の世界では珍しい要件です(ただし、C ++では一般的です)。一般に、検証コードをセッター内に配置すると問題なく機能します。
私のプロパティにはいくつかのプライベートセッターがあります。したがって、それらは私のデータクラスのコンストラクターでのみ設定されます。問題は、これが私の検証を容易にしないように見えることです
なぜそれが何かを変えるのでしょうか?プライベートセッター内で検証を処理します。検証が失敗した場合は、例外をスローします。コンストラクターは例外を処理しないため、オブジェクトをインスタンス化しようとしたコードに、そのメソッドからバブリングを続けます。そのコードが例外を処理したい場合(たとえば、ユーザーにエラーメッセージを表示したい場合)、そうすることができます。
確かに、無効な入力の場合に例外をスローすることは、必ずしも「ベストプラクティス」ではありません。その理由は、例外は通常、予期しない状況に備えて予約する必要があり、ユーザーが失敗して無効なデータを提供することは当然のことです。でも:
- コンストラクターは値を返すことができないため、これはコンストラクター内のデータ検証に使用できる唯一のオプションです。
- 最新のコンピューターは、ユーザーが画面上の変更を認識できるよりも速く例外を処理できるため、UIコードでは、例外処理のコストは基本的にごくわずかです。