Farkında gibi göründüğünüz gibi, iki dizeyi küçültmek ve karşılaştırmak, büyük / küçük harf karşılaştırmasını yok saymakla aynı şey değildir. Bunun pek çok nedeni var. Örneğin, Unicode standardı, aksanlı metnin birden çok şekilde kodlanmasına izin verir. Bazı karakterler, tek bir kod noktasında hem temel karakteri hem de aksan işaretini içerir. Bu karakterler aynı zamanda temel karakter olarak ve ardından bir aksan karakterini birleştirerek temsil edilebilir. Bu iki temsil tüm amaçlar için eşittir ve .NET Framework'teki kültüre duyarlı dize karşılaştırmaları, bunları CurrentCulture veya InvariantCulture (IgnoreCase ile veya onsuz) ile eşit olarak doğru şekilde tanımlayacaktır. Öte yandan, sıralı bir karşılaştırma onları yanlış bir şekilde eşitsiz olarak değerlendirecektir.
Ne yazık ki, switch
sıralı bir karşılaştırma dışında hiçbir şey yapmaz. Bir ASCII dosyasını katı şekilde tanımlanmış kodlarla ayrıştırmak gibi belirli uygulama türleri için sıralı bir karşılaştırma iyidir, ancak sıralı dizgi karşılaştırması diğer çoğu kullanım için yanlıştır.
Geçmişte doğru davranışı elde etmek için yaptığım şey sadece kendi switch deyimimi taklit etmekti. Bunu yapmanın birçok yolu var. Bunun bir yolu List<T>
, vaka dizileri ve temsilcilerden oluşan bir çift oluşturmaktır . Liste, uygun dizi karşılaştırması kullanılarak aranabilir. Eşleşme bulunduğunda, ilişkili delege çağrılabilir.
Diğer bir seçenek de, açık if
ifadeler zincirini yapmaktır . Yapı çok düzenli olduğu için bu genellikle göründüğü kadar kötü değildir.
Bununla ilgili harika olan şey, dizelerle karşılaştırırken kendi anahtar işlevselliğinizi taklit etmenin gerçekten herhangi bir performans cezası olmamasıdır. Sistem tamsayılarla yapabildiği gibi bir O (1) atlama tablosu yapmayacak, bu nedenle her dizeyi her seferinde bir tane olmak üzere karşılaştıracak.
Karşılaştırılacak çok sayıda durum varsa ve performans bir sorunsa, List<T>
yukarıda açıklanan seçenek sıralı bir sözlük veya karma tablo ile değiştirilebilir. Daha sonra performans, anahtar deyimi seçeneğiyle potansiyel olarak eşleşebilir veya bu seçeneği aşabilir.
Temsilciler listesine bir örnek:
delegate void CustomSwitchDestination();
List<KeyValuePair<string, CustomSwitchDestination>> customSwitchList;
CustomSwitchDestination defaultSwitchDestination = new CustomSwitchDestination(NoMatchFound);
void CustomSwitch(string value)
{
foreach (var switchOption in customSwitchList)
if (switchOption.Key.Equals(value, StringComparison.InvariantCultureIgnoreCase))
{
switchOption.Value.Invoke();
return;
}
defaultSwitchDestination.Invoke();
}
Elbette, CustomSwitchDestination temsilcisine bazı standart parametreler ve muhtemelen bir dönüş türü eklemek isteyeceksiniz. Ve daha iyi isimler yapmak isteyeceksiniz!
Vakalarınızın her birinin davranışı, örneğin farklı parametreler gerekliyse, bu şekilde çağrı yetkisi vermeye uygun değilse, zincirlenmiş if
ifadelerle sıkışıp kalırsınız . Bunu da birkaç kez yaptım.
if (s.Equals("house", StringComparison.InvariantCultureIgnoreCase))
{
s = "window";
}
else if (s.Equals("business", StringComparison.InvariantCultureIgnoreCase))
{
s = "really big window";
}
else if (s.Equals("school", StringComparison.InvariantCultureIgnoreCase))
{
s = "broken window";
}
ToUpperInvariant()
mıToLowerInvariant()
? Ayrıca, iki bilinmeyen dizgiyi karşılaştırmıyor, bilinmeyen bir dizgiyi bilinen bir dizeyle karşılaştırıyor. Bu nedenle, uygun büyük veya küçük harf gösterimini nasıl kodlayacağını bildiği sürece, anahtar bloğu iyi çalışmalıdır.