Benim sistemde sık sık havaalanı kodları (çalışabilir "YYZ"
, "LAX"
, "SFO"
vs.), bunlar (büyük harf olarak temsil 3 harfi) aynı formatta her zaman vardır. Sistem tipik olarak API talebi başına bu (farklı) kodların 25-50'sini ele alır, toplamda binden fazla tahsis ile, bunlar uygulamamızın birçok katmanından geçirilir ve eşitlik açısından sık sık karşılaştırılır.
Sadece biraz iyi çalıştı etrafında dizeleri geçen ile başladı ama hızlı bir şekilde 3 haneli kod beklenen bir yerde yanlış bir kod geçerek programlama hataları çok fark ettim. Ayrıca, büyük / küçük harfe duyarlı olmayan bir karşılaştırma yapmamız gereken sorunlarla karşılaştık ve bunun yerine hatalarla sonuçlandık.
Bundan sonra, dizeleri geçmeyi bırakmaya Airport
ve havaalanı kodunu alan ve doğrulayan tek bir kurucuya sahip bir sınıf oluşturmaya karar verdim .
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);
}
}
Bu, kodumuzu anlamayı çok daha kolay hale getirdi ve eşitlik kontrollerimizi, sözlük / set kullanımlarımızı basitleştirdik. Artık yöntemlerimiz Airport
, beklediğimiz gibi davranacağını kabul eden bir örneği kabul ederse , yöntem denetimlerimizi bir boş başvuru denetimine basitleştirdiğini biliyoruz.
Bununla birlikte, fark ettiğim şey, çöp toplama işleminin daha sık çalıştığıydı, bu Airport
da toplanmanın birçok örneğini izledim .
Bu Benim çözüm dönüştürmek için oldu class
bir içine struct
. Çoğunlukla bu sadece bir anahtar kelime değişikliği hariç olmak üzere, oldu GetHashCode
ve ToString
:
public override string ToString()
{
return Code ?? string.Empty;
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
Nerede default(Airport)
kullanılır durumda ele .
Sorularım:
Bir
Airport
sınıf ya da yapı oluşturmak genel olarak iyi bir çözüm müydü , yoksa yanlış problemi mi çözüyorum / türü yaratarak yanlış şekilde mi çözüyorum? İyi bir çözüm değilse, daha iyi bir çözüm nedir?Uygulamamın kullanıldığı örnekleri nasıl ele alması gerekir
default(Airport)
? Bir türdefault(Airport)
benim uygulama için saçma, bu yüzdenif (airport == default(Airport) { throw ... }
birAirport
(ve onunCode
özelliği) bir örnek almak operasyon için kritik yerlerde yapıyorum .
Notlar: C # / VB yapılı sorular - gözden geçirilmiş yapı için geçersiz sayılan sıfır varsayılan değerlerden nasıl kaçınılır? ve sorumu sormadan önce yapısını kullan ya da kullanma , ancak sorularımın kendi gönderisini garanti edecek kadar farklı olduğunu düşünüyorum.
default(Airport)
Sorunu çözmenin bir yolu , varsayılan örneklere izin vermemektir. Bunu parametresiz bir kurucu yazarak InvalidOperationException
veya NotImplementedException
içine atarak yapabilirsiniz .