私のシステムでは、私は頻繁に空港コード(で動作し"YYZ"
、"LAX"
、"SFO"
、など)、彼らはまったく同じ形式(大文字として表現3文字)に常にあります。システムは通常、APIリクエストごとにこれらの(異なる)コードの25〜50を処理し、合計で1,000を超える割り当てが行われ、アプリケーションの多くのレイヤーを通過して、頻繁に同等性が比較されます。
最初は文字列を渡すだけで、少しはうまくいきましたが、3桁のコードが予期される場所に間違ったコードを渡すことで、多くのプログラミングの間違いにすぐに気付きました。また、大文字と小文字を区別しない比較を行うことになっていた問題に遭遇しましたが、代わりにそうしなかったため、バグが発生しました。
このことから、文字列の受け渡しを停止してAirport
、空港コードを取得して検証する単一のコンストラクターを持つクラスを作成することにしました。
public sealed class Airport
{
public Airport(string code)
{
if (code == null)
{
throw new ArgumentNullException(nameof(code));
}
if (code.Length != 3 || !char.IsLetter(code[0])
|| !char.IsLetter(code[1]) || !char.IsLetter(code[2]))
{
throw new ArgumentException(
"Must be a 3 letter airport code.",
nameof(code));
}
Code = code.ToUpperInvariant();
}
public string Code { get; }
public override string ToString()
{
return Code;
}
private bool Equals(Airport other)
{
return string.Equals(Code, other.Code);
}
public override bool Equals(object obj)
{
return obj is Airport airport && Equals(airport);
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
public static bool operator ==(Airport left, Airport right)
{
return Equals(left, right);
}
public static bool operator !=(Airport left, Airport right)
{
return !Equals(left, right);
}
}
これにより、コードがはるかに理解しやすくなり、等価性チェック、辞書/セットの使用法が簡素化されました。メソッドがAirport
期待どおりに動作インスタンスをチェックをnull参照チェックに単純化したことがわかりました。
ただし、気づいたのは、ガベージコレクションが非常に頻繁に実行されていたことで、これを次の多くのインスタンスに追跡しました。 Airport
収集。
これに対する私の解決策は、に変換することでしclass
たstruct
。ほとんどの場合、キーワードの変更でしたがGetHashCode
、andを除きますToString
:
public override string ToString()
{
return Code ?? string.Empty;
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
default(Airport)
使用されるケースを処理するため。
私の質問:
Airport
クラスまたは構造を作成することは一般的に良い解決策でしたか、それともタイプを作成することで間違った問題を解決しますか、それとも間違った方法で解決しますか?それが良い解決策でない場合、より良い解決策は何ですか?アプリケーションは、
default(Airport)
が使用されるインスタンスをどのように処理する必要がありますか?タイプはdefault(Airport)
アプリケーションにとって無意味であるためif (airport == default(Airport) { throw ... }
、インスタンスAirport
(およびそのCode
プロパティ)を取得することが操作に不可欠な場所で行ってきました。
注:C#/ VB構造体の質問を検討しました。既定値がゼロのケースを回避する方法は、特定の構造体では無効と見なされますか?、および質問をする前にstructを使用するかどうかを選択しますが、私の質問はそれ自体の投稿を保証するほど十分に異なると思います。
default(Airport)
問題を解決する1つの方法は、デフォルトのインスタンスを単に禁止することです。それには、パラメータなしのコンストラクタを記述して、その中にスローするInvalidOperationException
かNotImplementedException
、または挿入します。