C #에서 ToUpper ()와 ToUpperInvariant ()의 차이점은 무엇입니까?


133

C #에서 ToUpper()ToUpperInvariant()? 의 차이점은 무엇 입니까?

결과가 다른 예를들 수 있습니까?


3
[조직]이 질문에 "국제화"태그가 있어야합니까?
jasso

답변:


154

ToUpper현재 문화를 사용합니다. ToUpperInvariant변하지 않는 문화를 사용합니다.

표준 예는 터키이며, "i"의 대문자는 "I"가 아닙니다.

차이점을 보여주는 샘플 코드 :

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);
    }
}

터키어에 대한 자세한 내용은이 터키 테스트 블로그 게시물을 참조하십시오 .

생략 된 문자 등에 대한 다양한 대문자 문제가 있다는 사실에 놀라지 않을 것입니다. 이것은 제가 머리 꼭대기에서 아는 한 가지 예일뿐입니다. -케이싱하고 "MAIL"과 비교합니다. 터키에서는 그다지 효과가 없었습니다 ...


45
haha 나는 그 생각을 읽었습니다 ... " '터키'에는 'i'라는 글자가 없습니다"
Jeff Mercado

거의 2019 년이며 Visual Studio에서 Unity 3D ımage의 필드 이름 Image과 Unity 3D의 Unable to find key name that matches 'rıght'날짜 및 시간에 대한 터키 지역 설정이있는 "영어"Windows 의 콘솔 에 내부 오류를 스팸으로 표시 하고 있습니다. 때때로 마이크로 소프트조차도 터키 테스트에 실패한 것처럼 보입니다 .PC의 언어는 터키어가 아니라 롤입니다.
Guney Ozsan

28

존의 대답은 완벽합니다. 방금 ToUpperInvariant을 호출하는 것과 동일 하게 추가하고 싶었습니다 ToUpper(CultureInfo.InvariantCulture).

따라서 Jon의 예제가 조금 더 단순 해집니다.

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 }, 
            }
        });
    }
}

나는 또한 더 멋진 글꼴이기 때문에 New Times Roman을 사용 했습니다.

속성이 상속 되기 때문에 두 컨트롤 대신 FormFont속성을 설정했습니다 .LabelFont

그리고 소형 (예 : 생산이 아닌) 코드를 좋아하기 때문에 다른 몇 줄을 줄였습니다.

나는 지금 당장 할 일이 낫지 않았다.


5
"존의 대답은 완벽하다." 중복 진술에 대해 이야기하십시오. ;)
krillgar

1
ToUpper 메소드에 매개 변수 과부하가 없습니까? 이전 버전이 있습니까? 나는 그것을 얻을 해달라고
batmaci

모르겠습니다. 여기에 설명되어 있습니다. msdn.microsoft.com/en-us/library/system.string.toupper.aspx
Tergiver


12

String.ToUpper그리고 String.ToLower다른 문화 주어진 다른 결과를 제공 할 수 있습니다. 가장 알려진 예는 터키어 예입니다 . 소문자 라틴어 "i"를 대문자로 변환하면 대문자 라틴어 "I"가 아니라 터키어 "I"가됩니다.

문화, 대문자-소문자, 소문자-대문자에 따라 I의 대문자

나에 관해서는 위의 그림 ( source ) 과 혼동 되어 터키 프로그램의 정확한 결과를 볼 수있는 프로그램 (아래 소스 코드 참조)을 작성했습니다.

# 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)

보다시피 :

  1. 대문자 소문자와 대문자 소문자는 변하지 않는 문화와 터키 문화에 대해 다른 결과를 제공합니다.
  2. 문화가 무엇이든 대문자와 소문자는 영향을 미치지 않습니다.
  3. Culture.CultureInvariant 터키 문자를 그대로 둡니다
  4. ToUpperToLower그것을 uppercasing 후 문자 lowercasing 즉, 가역적만큼 동일한 배양 하였다 모두 작업에 대해, 원래의 형태로 가져온다.

MSDN 에 따르면 Char.ToUpper와 Char.ToLower의 경우 터키어와 아제르 족은 단일 문자 케이싱 차이가있는 유일한 문화이기 때문에 영향을받는 유일한 문화입니다. 문자열의 경우 더 많은 문화권이 영향을받을 수 있습니다.


출력을 생성하는 데 사용되는 콘솔 응용 프로그램의 소스 코드 :

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})";
        }
    }
}

사례 테이블은 매우 도움이되었습니다. 감사!
VoteCoffee


2

영어에는 차이가 없습니다. 터키 문화에서만 차이를 찾을 수 있습니다.


13
그리고 터키어가 영어와 대문자 규칙이 다른 유일한 문화일까요? 나는 그것을 믿기가 어렵다.
Joel Mueller

3
가장 많이 사용되는 예는 터키어이지만 유일하지는 않습니다. 그리고 그것은 네 가지 다른 I를 가진 문화가 아닌 언어입니다. 터키어는 여전히 +1입니다.
Armstrongest

다른 사람이 있어야합니다. 대부분의 ppl은 어쨌든 프로그래밍에서 이러한 언어를 절대 만나지 않을 것입니다
Stefanvds

8
물론입니다. 웹 응용 프로그램은 전 세계에 열려 있으며 매개 변수를 설정하는 것이 좋습니다. 유니 코드를 수행하지 않는 레거시 데이터베이스에서 작업하는 경우 어떻게됩니까? 사용자 이름으로 어떤 문자를 허용 하시겠습니까? COBOL을 기반으로하는 레거시 ERP에 고객 이름을 입력해야하는 경우 어떻게해야합니까? 문화가 중요한 경우가 많습니다. 날짜와 숫자는 말할 것도 없습니다. 4.54는 일부 언어로 4,54로 작성되었습니다. 다른 언어가 존재하지 않는 척한다면 장기적으로는 멀지 않습니다.
Armstrongest

분명히 문화는 날짜와 숫자에 중요합니다. 대부분의 ppl은 toUpper와 toUpperInvariant에서 다른 결과를 가진 언어를 절대 만나지 않을 것이라고 말하고 있습니다.
Stefanvds
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.