どの返品スタイルを使用すればよいですか?
-
12-09-2019 - |
質問
これは、C# で使用される規則に関連しています。
2 つのパラメーター (X 座標と Y 座標) を持つメソッドがあります。これらの座標は、「タイル」が存在する可能性がある位置を表します。タイルがこれらの座標に存在する場合、メソッドはその番号を返します。これらの座標にタイルが存在しない場合、メソッドがどのように動作するべきか疑問に思います。
3 つのオプションが表示されます。
- 例外を使用します。メソッドがタイルを見つけられないたびに例外が発生する可能性があります。ただし、この状況は珍しいことではないため、このオプションは最悪のオプションです。
- 昔ながらの C++ の方法で実行し、タイルがない場合は -1 を返します。
- タイル番号を参照パラメータにして、タイルの有無を示すメソッドの戻り値の型をブール値に変更します。しかし、これは私には少し複雑に思えます。
それで、どうすればいいでしょうか?
解決
リターン-1ます。
これは、.NET Frameworkでも共通ですが、ちょうどC ++規則ではありません - 例えばString.IndexOfまたはリストを表すコントロールのSelectedIndexをのような特性のような方法。
編集
ちょうどあなたの質問(例外、パラメータから、-1を返す)での3つのオプションの、手の込んだ、返すことが-1移動するための方法です。例外は例外的な状況のためのもの、およびマイクロソフトのコーディングガイドラインは、可能な限りのパラメータを回避推奨しています。
私の見解では-1を返し、NULL可能int型を返す、またはタイルオブジェクトを返す(常に無効な値になるだろう提供)すべての許容ソリューションであり、あなたはあなたのアプリケーションの残りの部分と最も一致している方を選択すべきです。私はすべての開発者は、次のいずれかとのわずかな難しさを持って想像することはできません。
int tileNumber = GetTile(x,y);
if (tileNumber != -1)
{
... use tileNumber ...
}
int? result = GetTile(x,y);
if (result.HasValue)
{
int tileNumber = result.Value;
... use tileNumber ...
}
Tile tile = GetTile(x,y);
if (tile != null)
{
... use tile ...
}
私は、「NULL値可能型を返すよりもはるかに効率的」であるint型を使用する方法についてピーターRuderman氏のコメントを理解していません。私は何の違いは無視できるだろうと思っていると思います。
他のヒント
あなたはnullを返し、呼び出し元のコードにこれをチェックすることができます。
もちろん、あなたがNULL可能タイプを使用する必要があると思います:
int? i = YourMethodHere(x, y);
例外は例外的な場合のためのものであるため、例外を使用するのは 知られている そして 期待される エラー状況は「悪い」です。また、このエラー状況が発生することが予想されるため、このエラーを処理するためにどこでも try-catch を使用する可能性が高くなります。
唯一のエラー条件 (-1 など) が実際の値と混同しやすい場合は、戻り値をパラメーターにすることができます。負のタイル番号を指定できる場合は、これがより良い方法です。
null 許容 int は参照パラメータの代替として使用できる可能性がありますが、これを使用してオブジェクトを作成しているため、「エラー」が日常的なものである場合は、参照パラメータよりもこの方法の方が手間がかかる可能性があります。Roman が他の場所のコメントで指摘したように、C# とVB の問題 null 許容型 VB は導入が遅すぎて、C# のような優れた構文糖衣を提供できませんでした。
タイルが非負値のみである場合は、-1 を返すことがエラーを示す許容可能な従来の方法です。また、パフォーマンスとメモリの点でも最も安価になります。
他に考慮すべき点は、自己文書化です。-1 と例外を使用するのが慣例です。開発者がそれらを認識していることを確認するためにドキュメントを作成する必要があります。を使用して int?
return または参照パラメータは、それ自体を自己記述する方が適切であり、そうではありません。 必要とする 開発者がエラー状況の処理方法を知るためのドキュメント。もちろん :) 毎日歯をフロスするのと同じように、常に文書を作成する必要があります。
NULL可能戻り値を使用します。
int? GetTile(int x, int y) {
if (...)
return SomeValue;
else
return null;
}
これは明確なソリューションです。
は、別の可能性は、タイルオブジェクト自体、またはnullを返すようになります。
あなたは正しい2.私はオプションとなるだろう、そのような一般的な場合に例外をスローすると、パフォーマンスのために悪いかもしれ、およびoutパラメータを使用して、真または偽を返すことが読み便利しかしおかしくあります。
また、string.IndexOf()
方法を考えます。何も見つからない場合は、-1を返します。私はその例に従うと思います。
あなたは、-1を返すことができます。しかし、実際にクリックされたタイルを返すために良いかもしれない、と何のタイルがクリックされなかったことをイベントでは、シングルトンNullTileインスタンスへの参照を返します。このようにそれを行うことの利点は、あなたがそれだけでその数値を超えた全く本質的な意味を持たない数であるのではなく、返された各値に具体的な意味を与えるということです。型「NullTileは、」あなたのコードの他の読者のために疑いを少し残して、その意味についての非常に具体的です。
最良の選択肢は、同様にブール値を返すか、nullを返すことです。
例えばます。
bool TryGetTile(int x, int y, out int tile);
や、
int? GetTile(int x, int y);
「TryGetValue」パターンを好むために、いくつかの理由があります。クライアントコードは非常に単純であるので、一つには、それは、例えば、ブール値を返す:IF(TryGetValue(someValアウト)){/ *いくつかのコード* /}。密結合になる「魔法の数字」、それらのデザインで迅速作物アップとアウトファクタリング(-1、0、NULL、例外の特定のセットなどをキャッチに)ハードコードされたセンチネル値の比較を必要とするクライアントコードにこれを比較し雑用ます。
番兵、ヌル、または例外が、それはあなたがメカニズムが使用されているドキュメントを確認することは絶対不可欠だと予想されている場合。ドキュメントが存在しないか、または一般的なシナリオは、アクセスできない場合、あなたはあなたが単にヌル参照例外または他の悪い欠陥のために自分自身を設定している間違った選択をした場合、他の証拠に基づいて推測することがあります。これに対し、TryGetValue()パターンは、それだけの名前とメソッドのシグネチャによって自己文書にかなり近いです。
私はあなたが尋ねた質問で自分の意見を持っているが、それは上に述べていますし、私はそれに応じて投票してきました。
あなたがまたは少なくとも上記の回答のすべての拡張として、要求していないことを質問に関しては:私はアプリ間で一貫性の似たような状況に対する解決策を保つようにしてくださいだろう。言い換えれば、何でも答えあなたが落ち着く、アプリ内で同じそれを保つます。
この方法は、低レベルのライブラリの一部である場合、標準の.NETのデザインは、おそらくあなたのメソッドから例外をスローするように指示します。
このは、.NETフレームワークは、一般的にどのように動作するかです。あなたのより高いレベルの発信者があなたの例外をキャッチする必要があります。
あなたはUIイベントに応答しているので、パフォーマンスに影響を持つUIスレッドからこれをやっているように見えるしかし以来 - 私はジェイリッグスが既に提案し何を、nullを返し、そしてあなたの発信者がnullの戻り値をチェックしてくださいます。
私は2つの方法の中にそれを破ると思います。 CheckTileExists(x,y)
とGetTile(x,y)
のようなものを持っています。前者は、与えられた座標のタイルが存在するかどうかを示すブール値を返します。第二の方法は、無効な座標を与えられたときには、発信者が最初の呼び出しCheckTileExists()
なかっ示しているため、それは(例外をスローする必要があり、それが合法的に例外的な状況である以外、基本的に、あなたのオリジナルのポストに話をしているものです。のためにそれらが次々と呼ばれているイベントで、GetTile()
機能上のオーバーヘッドが無視できる程度になるようにスピードのためには、あなたはおそらく、これらの2つの方法がキャッシュを共有したいと思います。あなたが既に持っている場合、私は知りませんおそらくあなたは彼らに新しいクラスの2つのメソッドを作る必要がある上、または場合は、これらのメソッドを置くために、適切なオブジェクト。私見では、このアプローチのパフォーマンスの低下は無視できるとはるかにそれを上回るコードの明瞭度の増加である。
これは、座標で参照されているTile
オブジェクト作成した(または作成することができます)は可能ですか?もしそうなら何のタイルが与えられた座標に存在しない場合、あなたはそのタイルやnull
への参照を返すことができます:
public Tile GetTile(int x, int y) {
if (!TileExists(x, y))
return null;
// ... tile lookup here...
}