C # 'da ToUpper () ve ToUpperInvariant () arasındaki fark nedir?


133

C # arasındaki fark nedir ToUpper()ve ToUpperInvariant()?

Sonuçların farklı olabileceği bir örnek verebilir misiniz?


3
[Organizasyon] Bu soruda "uluslararasılaştırma" etiketi olmalı mı?
jasso

Yanıtlar:


154

ToUppermevcut kültürü kullanır. ToUpperInvariantdeğişmez kültürü kullanır.

Kanonik örnek, "i" nin büyük harfinin "ben" olmadığı Türkiye'dir.

Farkı gösteren örnek kod:

using System;
using System.Drawing;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;

public class Test
{
    [STAThread]
    static void Main()
    {
        string invariant = "iii".ToUpperInvariant();
        CultureInfo turkey = new CultureInfo("tr-TR");
        Thread.CurrentThread.CurrentCulture = turkey;
        string cultured = "iii".ToUpper();

        Font bigFont = new Font("Arial", 40);
        Form f = new Form {
            Controls = {
                new Label { Text = invariant, Location = new Point(20, 20),
                            Font = bigFont, AutoSize = true},
                new Label { Text = cultured, Location = new Point(20, 100),
                            Font = bigFont, AutoSize = true }
            }
        };        
        Application.Run(f);
    }
}

Türkçe hakkında daha fazla bilgi için bu Turkey Test blog gönderisine bakın .

Seçilmiş karakterlerle ilgili başka çeşitli büyük harf kullanımı sorunları olduğunu duymak beni şaşırtmaz. Bu, kafamın tepesinden bildiğim bir örnektir ... kısmen de yıllar önce Java'da beni ısırdığı için - bir dizgeyi "POSTA" ile karşılaştırmak. Türkiye'de pek işe yaramadı ...


45
haha şunu düşünerek okudum ... "'Türkiye' içinde 'i' harfi yok"
Jeff Mercado

Neredeyse 2019 ve tarih ve saat için Türkiye bölgesel ayarlarıyla "İngilizce" bir pencerede konsola dahili bir hata gönderen ve Unity 3D ımageiçin bir alan adı öneren Visual Studio'yu görüyorum . Görünüşe göre bazen Microsoft bile Türkiye testini geçemiyor, bir bilgisayarın dili Türkçe bile değil, sadece lol. ImageUnable to find key name that matches 'rıght'
Guney Ozsan

28

Jon'un cevabı mükemmel. Sadece aramakla ToUpperInvariantaynı şey olduğunu eklemek istedim ToUpper(CultureInfo.InvariantCulture).

Bu Jon'un örneğini biraz daha basitleştirir:

using System;
using System.Drawing;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;

public class Test
{
    [STAThread]
    static void Main()
    {
        string invariant = "iii".ToUpper(CultureInfo.InvariantCulture);
        string cultured = "iii".ToUpper(new CultureInfo("tr-TR"));

        Application.Run(new Form {
            Font = new Font("Times New Roman", 40),
            Controls = { 
                new Label { Text = invariant, Location = new Point(20, 20), AutoSize = true }, 
                new Label { Text = cultured, Location = new Point(20, 100), AutoSize = true }, 
            }
        });
    }
}

Ayrıca New Times Roman'ı kullandım çünkü daha güzel bir yazı tipi.

Özellik miras alındığı için iki denetim yerine Form's Fontözelliğini de ayarlıyorum .LabelFont

Ve sırf kompakt (örneğin, üretimi değil) kodu sevdiğim için diğer birkaç satırı azalttım.

Şu anda gerçekten yapacak daha iyi bir şeyim yoktu.


5
"Jon'un cevabı mükemmel." Gereksiz bir ifade hakkında konuşun. ;)
krillgar

1
ToUpper yönteminde benim için herhangi bir parametre aşırı yüklemesi yok mu? eski sürümde var mıydı? I dont get it
batmaci



12

String.ToUpperve String.ToLowerfarklı kültürlere göre farklı sonuçlar verebilir. En bilinen örnek, küçük harfli latin "i" nin büyük harfe dönüştürülmesinin büyük harfle yazılmış latin "I" ile sonuçlanmadığı ancak Türkçe "I" ile sonuçlandığı Türkçe örnektir .

Kültüre bağlı olarak I'nin büyük harf kullanımı, üst satır - küçük harf, alt satır - büyük harf

Bana gelince, yukarıdaki resimle ( kaynak ) bile kafa karıştırıcıydı , Türkçe örnek için tam çıktıyı görmek için bir program yazdım (aşağıdaki kaynak koduna bakın):

# Lowercase letters
Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish
English i - i (\u0069) | I (\u0049)     | I (\u0130)   | i (\u0069)     | i (\u0069)
Turkish i - ı (\u0131) | ı (\u0131)     | I (\u0049)   | ı (\u0131)     | ı (\u0131)

# Uppercase letters
Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish
English i - I (\u0049) | I (\u0049)     | I (\u0049)   | i (\u0069)     | ı (\u0131)
Turkish i - I (\u0130) | I (\u0130)     | I (\u0130)   | I (\u0130)     | i (\u0069)

Gördüğün gibi:

  1. Büyük harfli küçük harfler ve küçük büyük harfler değişmez kültür ve Türk kültürü için farklı sonuçlar verir.
  2. Kültür ne olursa olsun, büyük harflerin ve küçük harflerin küçük harflerin hiçbir etkisi yoktur.
  3. Culture.CultureInvariant Türk karakterleri olduğu gibi bırakıyor
  4. ToUpperve ToLowertersine çevrilebilir, yani bir karakteri büyük harfe dönüştürdükten sonra küçültmek, her iki işlem için de aynı kültür kullanıldığı sürece onu orijinal forma getirir.

Göre MSDN onlar tek karakterlik kasa farkları sadece onlar çünkü Char.ToUpper ve Char.ToLower Türkçesi ve Azeri yalnızca etkilenen kültürler vardır. İpler için, etkilenen daha fazla kültür olabilir.


Çıktı oluşturmak için kullanılan bir konsol uygulamasının kaynak kodu:

using System;
using System.Globalization;
using System.Linq;
using System.Text;

namespace TurkishI
{
    class Program
    {
        static void Main(string[] args)
        {
            var englishI = new UnicodeCharacter('\u0069', "English i");
            var turkishI = new UnicodeCharacter('\u0131', "Turkish i");

            Console.WriteLine("# Lowercase letters");
            Console.WriteLine("Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish");
            WriteUpperToConsole(englishI);
            WriteLowerToConsole(turkishI);

            Console.WriteLine("\n# Uppercase letters");
            var uppercaseEnglishI = new UnicodeCharacter('\u0049', "English i");
            var uppercaseTurkishI = new UnicodeCharacter('\u0130', "Turkish i");
            Console.WriteLine("Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish");
            WriteLowerToConsole(uppercaseEnglishI);
            WriteLowerToConsole(uppercaseTurkishI);

            Console.ReadKey();
        }

        static void WriteUpperToConsole(UnicodeCharacter character)
        {
            Console.WriteLine("{0,-9} - {1,10} | {2,-14} | {3,-12} | {4,-14} | {5,-12}",
                character.Description,
                character,
                character.UpperInvariant,
                character.UpperTurkish,
                character.LowerInvariant,
                character.LowerTurkish
            );
        }

        static void WriteLowerToConsole(UnicodeCharacter character)
        {
            Console.WriteLine("{0,-9} - {1,10} | {2,-14} | {3,-12} | {4,-14} | {5,-12}",
                character.Description,
                character,
                character.UpperInvariant,
                character.UpperTurkish,
                character.LowerInvariant,
                character.LowerTurkish
            );
        }
    }


    class UnicodeCharacter
    {
        public static readonly CultureInfo TurkishCulture = new CultureInfo("tr-TR");

        public char Character { get; }

        public string Description { get; }

        public UnicodeCharacter(char character) : this(character, string.Empty) {  }

        public UnicodeCharacter(char character, string description)
        {
            if (description == null) {
                throw new ArgumentNullException(nameof(description));
            }

            Character = character;
            Description = description;
        }

        public string EscapeSequence => ToUnicodeEscapeSequence(Character);

        public UnicodeCharacter LowerInvariant => new UnicodeCharacter(Char.ToLowerInvariant(Character));

        public UnicodeCharacter UpperInvariant => new UnicodeCharacter(Char.ToUpperInvariant(Character));

        public UnicodeCharacter LowerTurkish => new UnicodeCharacter(Char.ToLower(Character, TurkishCulture));

        public UnicodeCharacter UpperTurkish => new UnicodeCharacter(Char.ToUpper(Character, TurkishCulture));


        private static string ToUnicodeEscapeSequence(char character)
        {
            var bytes = Encoding.Unicode.GetBytes(new[] {character});
            var prefix = bytes.Length == 4 ? @"\U" : @"\u";
            var hex = BitConverter.ToString(bytes.Reverse().ToArray()).Replace("-", string.Empty);
            return $"{prefix}{hex}";
        }

        public override string ToString()
        {
            return $"{Character} ({EscapeSequence})";
        }
    }
}

Vaka tablosu çok yardımcı oldu. Teşekkürler!
VoteCoffee


2

ingilizcede fark yok. sadece türk kültüründe bir farklılık bulunabilir.


13
Büyük harf için İngilizce'den farklı kuralları olan dünyadaki tek kültürün Türkçe olduğuna emin misiniz? Buna inanmakta zorlanıyorum.
Joel Mueller

3
Türkçe en sık kullanılan örnek, ancak tek örnek değil. Ve dört farklı I'e sahip olan kültür değil, dildir. Yine de Türkçe için +1.
Armstrongest

Elbette başkaları da olmalı. çoğu kişi programlamada bu dilleri asla karşılamayacak
Stefanvds

8
Elbette yapacaklar. Web Uygulamaları dünyaya açıktır ve parametrelerinizi ayarlamak iyidir. Ya unicode yapmayan eski bir veritabanı üzerinde çalışıyorsanız? Kullanıcı adı olarak hangi karakterleri kabul edeceksiniz? COBOL üzerine kurulu bir Eski ERP'ye Müşteri adları eklemeniz gerekirse ne olur? Kültürün önemli olduğu birçok vaka. Tarihler ve sayılardan bahsetmiyorum bile. 4.54, bazı dillerde 4,54 olarak yazılmıştır. Diğer diller yokmuş gibi davranmak sizi uzun vadede çok uzağa götürmez.
Armstrongest

Açıkçası kültürler tarihler ve sayılar için önemlidir, sadece çoğu kişi toUpper ve toUpperInvariant'ta farklı sonuçlara sahip olan dilleri asla karşılamayacağını söylüyorum.
Stefanvds
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.