Runtime: .NET Core 3.0-> .NET 5.0์—์„œ string.IndexOf (string)๋กœ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ

์— ๋งŒ๋“  2020๋…„ 10์›” 22์ผ  ยท  76์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dotnet/runtime

๊ธฐ์ˆ 

.NET 5.0์„ ์ง€์›ํ•˜๋„๋ก ํŒจํ‚ค์ง€๋ฅผ ํ™•์žฅํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜์†” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฃผ์–ด์ง€๋ฉด :

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var actual = "Detail of supported commands\n============\n## Documentation produced for DelegateDecompiler, version 0.28.0 on Thursday, 22 October 2020 16:03\n\r\nThis file documents what linq commands **DelegateDecompiler** supports when\r\nworking with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF).\r\nEF has one of the best implementations for converting Linq `IQueryable<>` commands into database\r\naccess commands, in EF's case T-SQL. Therefore it is a good candidate for using in our tests.\r\n\r\nThis documentation was produced by compaired direct EF Linq queries against the same query implemented\r\nas a DelegateDecompiler's `Computed` properties. This produces a Supported/Not Supported flag\r\non each command type tested. Tests are groups and ordered to try and make finding things\r\neasier.\r\n\r\nSo, if you want to use DelegateDecompiler and are not sure whether the linq command\r\nyou want to use will work then clone this project and write your own tests.\r\n(See [How to add a test](HowToAddMoreTests.md) documentation on how to do this). \r\nIf there is a problem then please fork the repository and add your own tests. \r\nThat will make it much easier to diagnose your issue.\r\n\r\n*Note: The test suite has only recently been set up and has only a handful of tests at the moment.\r\nMore will appear as we move forward.*\r\n\r\n\r\n### Group: Unit Test Group\n#### [My Unit Test1](../TestGroup01UnitTestGroup/Test01MyUnitTest1):\n- Supported\n  * Good1 (line 1)\n  * Good2 (line 2)\n\r\n#### [My Unit Test2](../TestGroup01UnitTestGroup/Test01MyUnitTest2):\n- Supported\n  * Good1 (line 1)\n  * Good2 (line 2)\n\r\n\r\n\nThe End\n";

            var expected = "\n#### [My Unit Test2](";

            Console.WriteLine($"actual.Contains(expected): {actual.Contains(expected)}");
            Console.WriteLine($"actual.IndexOf(expected): {actual.IndexOf(expected)}");
        }
    }
}

.NET Core 3.0-> .NET 5.0์˜ ๋Ÿฐํƒ€์ž„์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.

.NET Core 3.0 :

actual.Contains(expected): True
actual.IndexOf(expected): 1475

.NET 5.0 :

actual.Contains(expected): True
actual.IndexOf(expected): -1

๊ตฌ์„ฑ

Windows 10 Pro ๋นŒ๋“œ 19041 x64
.NET Core 3.1.9
.NET 5.0.0-rc.2.20475.5

ํšŒ๊ท€?

์˜ˆ, .NET Core 3.1.9๋ฅผ ํ†ตํ•ด ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

area-System.Globalization question

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@tarekgh , ๋‚˜๋Š” Contains ์™€ IndexOf ์‚ฌ์ด์˜ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ€ ๊ทธ ์ž์ฒด๋กœ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ๋ถ„๋ช…ํžˆ IndexOf ๋กœ, ๋‹ค๋ฅธ ASCII ์ „์šฉ ๋ฌธ์ž์—ด ๋‚ด์—์„œ ํ•˜๋‚˜์˜ ASCII ์ „์šฉ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค (ASCII ์ „์šฉ ๋ฌธ์ž์—ด์— ๋ถ€๊ณผ ๋œ ๋กœ์ผ€์ผ ์ข…์† ๋™์ž‘์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!).

์ด๊ฒƒ์€ ๋กœ์ผ€์ผ / NLS / ICU ๊ด€๋ จ ๋ณ€๊ฒฝ์—์„œ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด / ๋Ÿฐํƒ€์ž„์ด ๊ทธ๋ ‡๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ .NET 5 RC 2์—์„œ ๊นจ์ง„ ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์ž…๋‹ˆ๋‹ค.

var actual = "\n\r\nTest";
var expected = "\nTest";

Console.WriteLine($"actual.IndexOf(expected): {actual.IndexOf(expected)}"); // => -1

์ •๋ง ๊ทธ๋ ‡๊ฒŒ ์ž‘๋™ํ• ๊นŒ์š”? ๋˜ํ•œ ์™œ? ์‹ค์ œ๋กœ ๋ฌด์—‡์„ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๊นŒ?

์ •๋ง ๊ณ„ํš๋œ ๋ณ€๊ฒฝ ์ด์—ˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ ICU๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ์˜๋„์  ์ธ ๋ณ€๊ฒฝ์ž…๋‹ˆ๋‹ค.

์ฃ„์†ก ํ•ฉ๋‹ˆ๋‹ค๋งŒ ์ด๊ฒƒ์ด ๊ณ„ํš๋œ ๋ณ€๊ฒฝ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋„ ๊ทธ๋Ÿฐ ๋ณ€๊ฒฝ์„ _ ๊ณ„ํš _ํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ .NET ํŒ€์˜ ์‚ฌ๋žŒ๋“ค์ด ํ•จ๊ป˜ ์•‰์•„ ํ† ๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ž์—ด "\ n \ r \ nTest"์— ICU๊ฐ€ ํ™œ์„ฑํ™” ๋œ "\ nTest"๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ, ๋ถ„๋ช…ํžˆ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

๊ทธ๋ฆฌ๊ณ  ์•„๋ฌด๋„ ๋ถˆํ‰ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ? ๊ธฐํšŒ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค!

์ด๊ฒƒ์€ ๊ณ„ํš๋˜๊ฑฐ๋‚˜ ์˜ˆ์ƒ๋˜๋Š” ๋ณ€๊ฒฝ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋งค์šฐ ์‹ฌ๊ฐํ•œ ๋ฒ„๊ทธ, ํฐ ํ˜ธํ™˜์„ฑ ์ฐจ๋‹จ๊ธฐ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ์ƒˆ๋กญ๊ณ  ์ด์‹ ๋œ .NET ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ์ƒˆ ๋Ÿฐํƒ€์ž„์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋‚ด๋ถ€์—์„œ ํ•˜์œ„ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค!

ICU๊ฐ€ ์–ด์ฐจํ”ผ ๋ผ์ธ ์—”๋”ฉ์— ๊ด€์‹ฌ์ด์žˆ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ผ๋ถ€ ๋กœ์ผ€์ผ์—๋Š” ๊ณ ์œ  ํ•œ ๋กœ์ผ€์ผ ๋ณ„ ์ค„ ๋์ด ์žˆ์Šต๋‹ˆ๊นŒ?

PS ์˜ˆ, ์„œ์ˆ˜ ํ”Œ๋ž˜๊ทธ์™€ ๊ฐ™์ด ๋ฌธํ™”์— ๋…๋ฆฝ์  ์ธ IndexOf ๋ณ€ํ˜•์„ ํ•ญ์ƒ ํ˜ธ์ถœํ•ด์•ผํ•œ๋‹ค๊ณ  ์ฃผ์žฅ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ .NET 5์—์„œ ์—ด์‹ฌํžˆ _that_ ๊นฐ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฒฐ์ • ํ–ˆ๋‹ค๋ฉด , ์ •์ƒ์ ์ธ ์„œ์ˆ˜ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? .NET 5 RC 2์—์„œ ๋ณผ ์ˆ˜์žˆ๋Š” ํ˜„์žฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋ณด๋‹ค ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋” ์ ๊ฒŒ ์ค‘๋‹จ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ IndexOf ํ•ญ์ƒ ๋ฌธํ™” ๋ณ„ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ ์„œ์ˆ˜ ํ”Œ๋ž˜๊ทธ์—†์ด IndexOf ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ _tons_ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. _ ์ผํ•˜๋Š” ๋ฐ ์ต์ˆ™ ํ•จ _ (์ ์–ด๋„ ์ผ๋ถ€ / ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ). ๊ทธ๋ฆฌ๊ณ  .NET 5 ์—…๋ฐ์ดํŠธ ํ›„ ์ž‘๋™์ด ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  76 ๋Œ“๊ธ€

ํ—‰

์ด ์˜์—ญ์— ๋Œ€ํ•œ ๊ตฌ๋…์ž ํƒœ๊ทธ ์ง€์ • : @tarekgh , @safern , @krwq
๊ตฌ๋…ํ•˜๋ ค๋ฉด area-owners.md์˜ ์ •๋ณด๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ด๊ฒƒ์€ .NET 5.0์—์„œ NLS ๋Œ€์‹  ICU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „ํ™˜ ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด ์„ค๊ณ„์— ์˜ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๊ตฌ์„ฑ ์Šค์œ„์น˜ System.Globalization.UseNls ์„ (๋ฅผ) ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ๋™์ž‘์œผ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ ICU๊ฐ€ ๋” ์ •ํ™•ํ•˜๊ณ  ICU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€๋ฉด OS๊ฐ„์— ์ผ๊ด€์„ฑ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ๊ทธ๋ ‡๊ฒŒํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

IndexOf ๋ฅผ) Contains ๋กœ ์ž‘๋™ ์‹œํ‚ค๋ ค๋ฉด ๊ทธ ๋•Œ ์„œ์ˆ˜ ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

C# actual.IndexOf(expected, StringComparison.Ordinal)

๊ตฌ์„ฑ ์Šค์œ„์น˜ System.Globalization.UseNls๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ๋™์ž‘์œผ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜์žˆ๋Š” ์˜ต์…˜์ด ์žˆ์ง€๋งŒ ICU๊ฐ€ ๋” ์ •ํ™•ํ•˜๊ณ  ICU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€๋ฉด OS๊ฐ„์— ์ผ๊ด€์„ฑ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ๊ทธ๋ ‡๊ฒŒํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ, netcoreapp3.1 ๋ฅผ ๋Œ€์ƒ์œผ๋กœํ•˜๋Š” Unix์—์„œ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋™์ž‘์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

 santifdezm ๎‚ฐ DESKTOP-1J7TFMI ๎‚ฐ ~ ๎‚ฐ experimental ๎‚ฑ indexof ๎‚ฐ $ ๎‚ฐ  /home/santifdezm/experimental/indexof/bin/Debug/netcoreapp3.1/linux-x64/publish/indexof
actual.Contains(expected): True
actual.IndexOf(expected): -1

Ordinal ๋น„๊ต์™€ ํ•จ๊ป˜ @tarekgh ๋กœ ์˜ˆ์ƒ ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 santifdezm ๎‚ฐ DESKTOP-1J7TFMI ๎‚ฐ ~ ๎‚ฐ experimental ๎‚ฑ indexof ๎‚ฐ $ ๎‚ฐ /home/santifdezm/experimental/indexof/bin/Debug/net5.0/linux-x64/publish/indexof
actual.Contains(expected): True
actual.IndexOf(expected): 1475

์†Œ์Šค ๋ฌธ์ž์—ด์— \r\n ๋ฐ \n ๊ฐ€ ํ˜ผํ•ฉ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ์‹คํŒจํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. \r\n ์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋ฅผ \n ๋กœ ๋ฐ”๊พธ๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ชจ๋“  ๊ฒƒ์„ \r\n ๋งŒ๋“ค ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ICU์˜ ๋น„๊ต์—์„œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ ์˜ค๋Š” ๊ฒƒ์€ ๋‹จ์ง€ ํ˜ผํ•ฉ์ž…๋‹ˆ๋‹ค.

Twitter์—๋ณด๊ณ  ๋œ ๋ฌธ์ œ๋Š” 5.0 ๋Ÿฐํƒ€์ž„ ๋‚ด ์—์„œ ๋™์ผํ•œ ์ž…๋ ฅ ์œผ๋กœ string.IndexOf ํ•œ๋‹ค๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

https://twitter.com/jbogard/status/1319381273585061890?s=21

ํŽธ์ง‘ : ์œ„๋Š” ์˜คํ•ด์˜€์Šต๋‹ˆ๋‹ค.

@GrabYourPitchforks ๋ฌธ์ œ ์ œ๋ชฉ์„ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๊ธฐ์ˆ ์  ์ธ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด๋ฏ€๋กœ Windows ๋ฐ Unix์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

์„ค๋ช…์„ ์œ„ํ•ด Jimmy๋ฅผ ์˜คํ”„๋ผ์ธ์œผ๋กœ ํ•‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์˜ ์›๋ž˜ ๋ฌธ์ œ ๋ณด๊ณ ์„œ๋ฅผ ์˜คํ•ดํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 280 ์ž ํฌ๋Ÿผ์ด ๋ฒ„๊ทธ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ํ•ญ์ƒ ํšจ์œจ์ ์ธ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ;)

๋ช…ํ™•ํžˆํ•˜๊ธฐ ์œ„ํ•ด Contains API๋Š” ์„œ์ˆ˜ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋น„๊ต ํ”Œ๋ž˜๊ทธ๊ฐ€์—†๋Š” IndexOf ์€ ์„œ ์ˆ˜๊ฐ€ ์•„๋‹Œ ์–ธ์–ด ์—ฐ์‚ฐ์ž…๋‹ˆ๋‹ค. ํฌํ•จ ๋™์ž‘์„ IndexOf์™€ ๋น„๊ตํ•˜๋ ค๋ฉด IndexOf(expected, StringComparison.Ordinal) ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์ฐจ์ด์ ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„ ๋ณด๋ ค๋ฉด https://docs.microsoft.com/en-us/dotnet/csharp/how-to/compare-strings ๊ฐ€ ์œ ์šฉํ•œ ๋งํฌ์ž…๋‹ˆ๋‹ค.

ํŠธ์œ„ํ„ฐ์—์„œ ํ•ด๋ช…์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ๋ฃจํ”„์—์„œ IndexOf ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ง€ ํ‘œ์ค€ 3.0 ๋Œ€ 5.0 ํ–‰๋™ ์ฐจ์ด ๋ณด๊ณ ์„œ์ž…๋‹ˆ๋‹ค.

@GrabYourPitchforks ํŠธ์œ„ํ„ฐ ํšŒ์‹ ์— https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu ๋งํฌ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์ด์ „ ๋™์ž‘์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ตฌ์„ฑ ์Šค์œ„์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํŠธ์œ„ํ„ฐ์—์„œ ํ•ด๋ช…์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ๋ฃจํ”„์—์„œ IndexOf๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ง€ ํ‘œ์ค€ 3.0 ๋Œ€ 5.0 ํ–‰๋™ ์ฐจ์ด ๋ณด๊ณ ์„œ์ž…๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, @GrabYourPitchforks ... ์ด๊ฒƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„์— ๋”ฐ๋ผ ๋‹ซ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋” ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด NLS๋กœ ๋‹ค์‹œ ์ „ํ™˜ํ•˜์ง€ ์•Š๊ณ  ์ด์ „ ๋™์ž‘์„ ์–ป์œผ๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์‹ญ์‹œ์˜ค.

```C #
CultureInfo.CurrentCulture.CompareInfo.IndexOf (์‹ค์ œ, ์˜ˆ์ƒ, CompareOptions.IgnoreSymbols)

```C#
    actual.IndexOf(expected, StringComparison.Ordinal)

๋Œ€์‹ ์—

C# actual.IndexOf(expected)

์›ํ•˜๋Š” ๋™์ž‘์„ ์–ป์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋งํฌ ๋œ ICU ๊ด€๋ จ ๋ฌธ์„œ (https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/)์—์„œ \r\n ๋Œ€ \n ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์„ธ๊ณ„ํ™” -icu).

์ •๋ง ๊ณ„ํš๋œ ๋ณ€๊ฒฝ ์ด์—ˆ์Šต๋‹ˆ๊นŒ?

@ForNeVeR ICU์™€ NLS์˜ ๋ชจ๋“  ์ฐจ์ด์ ์„ ๋‚˜์—ดํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ๋Š” ICU ๋กœ์˜ ์ „ํ™˜์˜ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด Contains ์˜ ๊ฒฐ๊ณผ๋ฅผ StringComparison ๋งค๊ฐœ ๋ณ€์ˆ˜์—†์ด IndexOf ์™€ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ „ ๋™์ž‘์„ ์–ป์„ ์ˆ˜์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์œ„์— ๋‚˜์—ดํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋ณด๊ณ ์„œ์—์„œ IndexOf์˜ ์‚ฌ์šฉ์€ Ordinal ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋ฉฐ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์–ธ์–ด ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์–ธ์–ด ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜์žˆ๋Š” ํ˜„์žฌ ๋ฌธํ™”์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •๋ง ๊ณ„ํš๋œ ๋ณ€๊ฒฝ ์ด์—ˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ ICU๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ์˜๋„์  ์ธ ๋ณ€๊ฒฝ์ž…๋‹ˆ๋‹ค. Windows๋Š” ํ˜„์žฌ NLS๋ฅผ ํ†ตํ•ด ICU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šน๊ฒฉํ•ฉ๋‹ˆ๋‹ค. ICU๋Š” ์–ด์จŒ๋“  ๋ฏธ๋ž˜์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ICU๋Š” Windows / Linux / OSX ๋˜๋Š” ์ง€์›๋˜๋Š” ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์ผ๊ด€๋œ ๋™์ž‘์„ ํ•  ์ˆ˜์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ICU๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์ด ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์„ธ๊ณ„ํ™” ๋™์ž‘์„ ์‚ฌ์šฉ์ž ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์„œ์— ํ‘œ์‹œ๋œ๋Œ€๋กœ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ „ ๋™์ž‘์œผ๋กœ ๋‹ค์‹œ ์ „ํ™˜ ํ•  ์ˆ˜์žˆ๋Š” ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ์กฐ ๋œ ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด Windows์˜ ICU / NLS ๋™์ž‘์€ ์‹ค์ œ ํ™˜๊ฒฝ์˜ icu.dll ๊ฐ€์šฉ์„ฑ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์ „ํ™˜ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ฒŒ์‹œ ๋œ ๋…๋ฆฝํ˜• ์•ฑ์— ํฐ ๋†€๋ผ์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ICU๊ฐ€ ๋ชจ๋“  ๋Œ€์ƒ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šค์œ„์น˜๊ฐ€ ๊ฒฐ์ •๋œ ๊ฒฝ์šฐ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด .NET์ด ICU๋ฅผ ์ œ๊ณต ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ ํƒ์  ๋Ÿฐํƒ€์ž„ ์ข…์†์„ฑ์€ ์ƒํ™ฉ์„ ๋”์šฑ ์žฌ๋ฏธ์žˆ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ICU๊ฐ€ ๋ชจ๋“  ๋Œ€์ƒ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šค์œ„์น˜๊ฐ€ ๊ฒฐ์ •๋œ ๊ฒฝ์šฐ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด .NET์ด ICU๋ฅผ ์ œ๊ณต ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ ํƒ์  ๋Ÿฐํƒ€์ž„ ์ข…์†์„ฑ์€ ์ƒํ™ฉ์„ ๋”์šฑ ์žฌ๋ฏธ์žˆ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ด์ œ ICU๊ฐ€ NuGet ํŒจํ‚ค์ง€๋กœ ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค. ์•ฑ์€ ์ด๋Ÿฌํ•œ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์ฒด ํฌํ•จ ๋œ ์•ฑ์ด ICU๋ฅผ ๊ฐ–๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ ์˜

@tarekgh , ๋‚˜๋Š” Contains ์™€ IndexOf ์‚ฌ์ด์˜ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ€ ๊ทธ ์ž์ฒด๋กœ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ๋ถ„๋ช…ํžˆ IndexOf ๋กœ, ๋‹ค๋ฅธ ASCII ์ „์šฉ ๋ฌธ์ž์—ด ๋‚ด์—์„œ ํ•˜๋‚˜์˜ ASCII ์ „์šฉ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค (ASCII ์ „์šฉ ๋ฌธ์ž์—ด์— ๋ถ€๊ณผ ๋œ ๋กœ์ผ€์ผ ์ข…์† ๋™์ž‘์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!).

์ด๊ฒƒ์€ ๋กœ์ผ€์ผ / NLS / ICU ๊ด€๋ จ ๋ณ€๊ฒฝ์—์„œ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด / ๋Ÿฐํƒ€์ž„์ด ๊ทธ๋ ‡๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ .NET 5 RC 2์—์„œ ๊นจ์ง„ ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์ž…๋‹ˆ๋‹ค.

var actual = "\n\r\nTest";
var expected = "\nTest";

Console.WriteLine($"actual.IndexOf(expected): {actual.IndexOf(expected)}"); // => -1

์ •๋ง ๊ทธ๋ ‡๊ฒŒ ์ž‘๋™ํ• ๊นŒ์š”? ๋˜ํ•œ ์™œ? ์‹ค์ œ๋กœ ๋ฌด์—‡์„ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๊นŒ?

์ •๋ง ๊ณ„ํš๋œ ๋ณ€๊ฒฝ ์ด์—ˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ ICU๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ์˜๋„์  ์ธ ๋ณ€๊ฒฝ์ž…๋‹ˆ๋‹ค.

์ฃ„์†ก ํ•ฉ๋‹ˆ๋‹ค๋งŒ ์ด๊ฒƒ์ด ๊ณ„ํš๋œ ๋ณ€๊ฒฝ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋„ ๊ทธ๋Ÿฐ ๋ณ€๊ฒฝ์„ _ ๊ณ„ํš _ํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ .NET ํŒ€์˜ ์‚ฌ๋žŒ๋“ค์ด ํ•จ๊ป˜ ์•‰์•„ ํ† ๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ž์—ด "\ n \ r \ nTest"์— ICU๊ฐ€ ํ™œ์„ฑํ™” ๋œ "\ nTest"๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ, ๋ถ„๋ช…ํžˆ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

๊ทธ๋ฆฌ๊ณ  ์•„๋ฌด๋„ ๋ถˆํ‰ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ? ๊ธฐํšŒ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค!

์ด๊ฒƒ์€ ๊ณ„ํš๋˜๊ฑฐ๋‚˜ ์˜ˆ์ƒ๋˜๋Š” ๋ณ€๊ฒฝ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋งค์šฐ ์‹ฌ๊ฐํ•œ ๋ฒ„๊ทธ, ํฐ ํ˜ธํ™˜์„ฑ ์ฐจ๋‹จ๊ธฐ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ์ƒˆ๋กญ๊ณ  ์ด์‹ ๋œ .NET ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ์ƒˆ ๋Ÿฐํƒ€์ž„์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋‚ด๋ถ€์—์„œ ํ•˜์œ„ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค!

ICU๊ฐ€ ์–ด์ฐจํ”ผ ๋ผ์ธ ์—”๋”ฉ์— ๊ด€์‹ฌ์ด์žˆ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ผ๋ถ€ ๋กœ์ผ€์ผ์—๋Š” ๊ณ ์œ  ํ•œ ๋กœ์ผ€์ผ ๋ณ„ ์ค„ ๋์ด ์žˆ์Šต๋‹ˆ๊นŒ?

PS ์˜ˆ, ์„œ์ˆ˜ ํ”Œ๋ž˜๊ทธ์™€ ๊ฐ™์ด ๋ฌธํ™”์— ๋…๋ฆฝ์  ์ธ IndexOf ๋ณ€ํ˜•์„ ํ•ญ์ƒ ํ˜ธ์ถœํ•ด์•ผํ•œ๋‹ค๊ณ  ์ฃผ์žฅ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ .NET 5์—์„œ ์—ด์‹ฌํžˆ _that_ ๊นฐ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฒฐ์ • ํ–ˆ๋‹ค๋ฉด , ์ •์ƒ์ ์ธ ์„œ์ˆ˜ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? .NET 5 RC 2์—์„œ ๋ณผ ์ˆ˜์žˆ๋Š” ํ˜„์žฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋ณด๋‹ค ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋” ์ ๊ฒŒ ์ค‘๋‹จ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ IndexOf ํ•ญ์ƒ ๋ฌธํ™” ๋ณ„ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ ์„œ์ˆ˜ ํ”Œ๋ž˜๊ทธ์—†์ด IndexOf ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ _tons_ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. _ ์ผํ•˜๋Š” ๋ฐ ์ต์ˆ™ ํ•จ _ (์ ์–ด๋„ ์ผ๋ถ€ / ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ). ๊ทธ๋ฆฌ๊ณ  .NET 5 ์—…๋ฐ์ดํŠธ ํ›„ ์ž‘๋™์ด ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ASCII ์ „์šฉ ๋ฌธ์ž์—ด ๋‚ด์—์„œ ํ•˜๋‚˜์˜ ASCII ์ „์šฉ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜์—†๋Š” IndexOf์ž…๋‹ˆ๋‹ค (ASCII ์ „์šฉ ๋ฌธ์ž์—ด์— ์ ์šฉ๋œ ๋กœ์ผ€์ผ ์ข…์† ๋™์ž‘์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!).

ASCII๋Š” ๋กœ์ผ€์ผ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค. http://userguide.icu-project.org/collation/concepts ๋งํฌ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ASCII ๋ฌธ์ž์˜ ๋™์ž‘์ด ๋ฌธํ™”์— ๋”ฐ๋ผ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ์ง€ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์‹ญ์‹œ์˜ค.

For example, in the traditional Spanish sorting order, "ch" is considered a single letter. All words that begin with "ch" sort after all other words beginning with "c", but before words starting with "d".
Other examples of contractions are "ch" in Czech, which sorts after "h", and "lj" and "nj" in Croatian and Latin Serbian, which sort after "l" and "n" respectively.

๋˜ํ•œ ICU๋Š” ๋งŽ์€ ์ „๋ฌธ๊ฐ€๋“ค์ด ์ž˜ ์ƒ๊ฐํ•˜๋Š” Unicode Standard์—์„œ ๋ฐ์ดํ„ฐ์™€ ๋™์ž‘์„ ์„ ํƒํ•œ๋‹ค๋Š” ์ ์„ ๋ถ„๋ช…ํžˆํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. @GrabYourPitchforks ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์—ฌ๊ธฐ์„œ ์ด์•ผ๊ธฐํ•˜๊ณ ์žˆ๋Š” \r\n\ ์‚ฌ๊ฑด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๊ฒŒ์‹œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•œํŽธ, ํŠนํžˆ ๋‹ค์Œ์„ ์–ธ๊ธ‰ํ•˜๋Š” ์„น์…˜์—์„œ https://unicode.org/reports/tr29/ ๋ฌธ์„œ์— ์ต์ˆ™ํ•ด ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Do not break between a CR and LF. Otherwise, break before and after controls.
--
GB3 | CR | ร— | LF
GB4 | (Control \| CR \| LF) | รท | ย 
GB5 | ย  | รท | (Control \| CR \| LF)

ICU๊ฐ€ ์–ด์ฐจํ”ผ ๋ผ์ธ ์—”๋”ฉ์— ๊ด€์‹ฌ์ด์žˆ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ผ๋ถ€ ๋กœ์ผ€์ผ์—๋Š” ๊ณ ์œ  ํ•œ ๋กœ์ผ€์ผ ๋ณ„ ์ค„ ๋์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ๋งˆ์ง€๋ง‰ ๋‹จ๋ฝ์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

์ฃ„์†กํ•˜์ง€๋งŒ ์ด๊ฒƒ์ด ๊ณ„ํš๋œ ๋ณ€๊ฒฝ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋„ ๊ทธ๋Ÿฌํ•œ ๋ณ€๊ฒฝ์„ ๊ณ„ํšํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ .NET ํŒ€์˜ ์‚ฌ๋žŒ๋“ค์ด ํ•จ๊ป˜ ์•‰์•„ ํ† ๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ๊ณ„ํš๋˜๊ฑฐ๋‚˜ ์˜ˆ์ƒ๋˜๋Š” ๋ณ€๊ฒฝ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋งค์šฐ ์‹ฌ๊ฐํ•œ ๋ฒ„๊ทธ, ํฐ ํ˜ธํ™˜์„ฑ ์ฐจ๋‹จ๊ธฐ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ์ƒˆ๋กญ๊ณ  ์ด์‹ ๋œ .NET ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ์ƒˆ ๋Ÿฐํƒ€์ž„์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋‚ด๋ถ€์—์„œ ํ•˜์œ„ ๋ฌธ์ž์—ด์„ ์ฐพ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค!

์ด๊ฒƒ์€ ์ž˜ ๊ณ„ํš๋œ ์ž‘์—…์ด๋ฉฐ ๊นŠ์ด ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ž˜ ์ „์— ๊ฒŒ์‹œํ•˜๊ณ  ๊ณต๊ฐœ์ ์œผ๋กœ ๊ณต์œ  ํ•œ https://github.com/dotnet/runtime/issues/826 ๋ฌธ์ œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์„ธ๊ณ„ํ™” ๋™์ž‘์€ .NET๋ฟ๋งŒ ์•„๋‹ˆ๋ผ OS ๋ฐ ๊ธฐํƒ€ ํ”Œ๋žซํผ์—์„œ๋„ ์–ธ์ œ๋“ ์ง€ ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ์Œ์„ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•ฑ์ด ์‚ฌ์šฉํ•˜๋Š” ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ํŠน์ • ICU ๋ฒ„์ „์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ICU ์•ฑ ๋กœ์ปฌ ๊ธฐ๋Šฅ์„ ์ง€์›ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์‚ฌ์‹ค์€ Windows ์ž์ฒด๊ฐ€ ICU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ™๋ณดํ•˜๋Š” ๊ณผ์ •์— ์žˆ์œผ๋ฉฐ ์–ธ์  ๊ฐ€๋Š” ICU ๋™์ž‘์ด ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„œ์ˆ˜ ๊นƒ๋ฐœ์ฒ˜๋Ÿผ. ๊ทธ๋Ÿฌ๋‚˜ .NET 5์—์„œ ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ต๊ฒŒํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค๋ฉด ์ •์ƒ์ธ ์„œ์ˆ˜ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? .NET 5 RC 2์—์„œ ๋ณผ ์ˆ˜์žˆ๋Š” ํ˜„์žฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋ณด๋‹ค ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋” ์ ๊ฒŒ ์ค‘๋‹จ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ์šฐ๋ฆฌ๋Š” ์ด์ „์— Silverlight ๋ฆด๋ฆฌ์Šค ์ค‘์— ์„œ์ˆ˜ ๋™์ž‘์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์—๋ณด๊ณ  ๋œ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ IndexOf ์™€ ๊ฐ™์€ ๊ฒƒ์„ ํ˜ธ์ถœ ํ•  ๋•Œ ์˜์‹์„ ๊ฐ–๊ณ  ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ StringComparison ํ”Œ๋ž˜๊ทธ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋” ๋งŽ์€ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์ด ์ƒ๊ฐ ํ•ด๋‚ผ ์ˆ˜์žˆ๋Š” ๋ชจ๋“  ์•„์ด๋””์–ด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ IndexOf๊ฐ€ ํ•ญ์ƒ ๋ฌธํ™” ๋ณ„ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ ํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์„œ์ˆ˜ ํ”Œ๋ž˜๊ทธ์—†์ด IndexOf๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ˆ˜๋งŽ์€ ์ฝ”๋“œ๊ฐ€ ์žˆ๊ณ  ๊ทธ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋ชจ๋‘ ์ดํ•ดํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค (์ผ๋ถ€ / ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, ์ ์–ด๋„). ๊ทธ๋ฆฌ๊ณ  .NET 5 ์—…๋ฐ์ดํŠธ ํ›„ ์ž‘๋™์ด ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ „ ๋™์ž‘์œผ๋กœ ๋‹ค์‹œ ์ „ํ™˜ ํ•  ์ˆ˜์žˆ๋Š” ๊ตฌ์„ฑ ์Šค์œ„์น˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. System.Globalization.UseNls๋ฅผ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค.

@tarekgh , ์ฒ ์ €ํ•œ ์„ค๋ช…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์ง€๊ธˆ์€์ด ํŠน์ • \r\n ๋™์ž‘์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด ํŠน์ • ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ ํ•  ๋•Œ IndexOf "Grapheme Cluster Boundary Rules"(๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ ‡๊ฒŒํ•ด์•ผํ•˜๋Š”์ง€ ์—ฌ๋ถ€)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์œ ๋‹ˆ ์ฝ”๋“œ ์‚ฌ์–‘์ด ์—ฌ๊ธฐ์— ๊ด€๋ จ์ด ์žˆ๋”๋ผ๋„ https://unicode.org/reports/tr29/ ๋ฅผ ์ฝ์–ด ๋ณด๋ฉด ๋งˆ์ง€๋ง‰ \n ์™€ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์ด ๊ธˆ์ง€๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์‹  ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค CR | ร— | LF ๋˜์–ด ์žˆ๋Š”๋ฐ, ร— ๋Š” "๊ฒฝ๊ณ„ ์—†์Œ (์—ฌ๊ธฐ์—์„œ ์ค‘๋‹จ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Œ)"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹œํ€€์Šค๋ฅผ ๋Š์„ ๋•Œ \r\n\n , ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ž์™€ ๋‘ ๋ฒˆ์งธ ๋ฌธ์ž ์‚ฌ์ด์— "๋ถ„๋ฆฌ"๋ฅผ ๋‘๋Š” ๊ฒƒ๋งŒ ๊ธˆ์ง€ํ•˜์ง€๋งŒ ์„ธ ๋ฒˆ์งธ ๋ฌธ์ž ์•ž์— "๋ถ„๋ฆฌ"๋ฅผ ๋‘๋Š” ๊ฒƒ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €๋Š” \r\n\n ๋ฅผ ๋‘ ๊ฐœ์˜ ๋ถ„๋ฆฌ ๋œ "๋ฌธ์ž ์†Œ ํด๋Ÿฌ์Šคํ„ฐ"๋กœ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. IndexOf ๊ฐ€ ์ „์ฒด ๋ฌธ์ž ์†Œ ํด๋Ÿฌ์Šคํ„ฐ์™€ ์ผ์น˜ํ•ด์•ผํ•˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ผ๋ถ€๋ฅผ ์ ˆ๋Œ€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋”๋ผ๋„ ์—ฌ์ „ํžˆ ํ•˜์œ„ ๋ฌธ์ž์—ด \nTest ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. \n\r\nTest .

๋˜ํ•œ ICU ๋ฐ / ๋˜๋Š” ์œ ๋‹ˆ ์ฝ”๋“œ ์‚ฌ์–‘์— ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ ๋Ÿฐํƒ€์ž„ / ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€์ด ํŠน์ • ์˜ˆ์ œ์—์„œ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ด์•ผํ•œ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ IndexOf ์™€ ๊ฐ™์€ ๊ฒƒ์„ ํ˜ธ์ถœ ํ•  ๋•Œ ์˜์‹์„ ๊ฐ–๊ณ  ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ StringComparison ํ”Œ๋ž˜๊ทธ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋” ๋งŽ์€ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์ด ์ƒ๊ฐ ํ•ด๋‚ผ ์ˆ˜์žˆ๋Š” ๋ชจ๋“  ์•„์ด๋””์–ด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

_ (ํ•„์š”ํ•œ ๋ฉด์ฑ… ์กฐํ•ญ : ์ €๋Š” ReSharper๋ฅผ ํฌํ•จํ•œ ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์—์„œ JetBrains์—์„œ ์ผํ•ฉ๋‹ˆ๋‹ค.) _

์ฒ˜์Œ์—๋Š” ๊ด‘๊ณ ์ฒ˜๋Ÿผ ๋“ค๋ฆฌ์ง€ ์•Š๊ฒŒ์ด ์ ์„ ์—ฌ๊ธฐ์— ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์ง„ ์•Š์•˜์ง€๋งŒ, ์ด๊ฒƒ์ด ๋งค์šฐ ๊ด€๋ จ์ด์žˆ๋Š” ๊ฒƒ ๊ฐ™์•„์„œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ReSharper๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ IndexOf ํ˜ธ์ถœํ•˜๋Š” ์‚ฌ์šฉ์ž ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋‹ค์Œ ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
image

_ (์ด ์Šค๋ ˆ๋“œ์— ์ฐธ์—ฌํ•˜๊ธฐ ์ „์—๋Š”์ด ํŠน์ • ReSharper ์ง„๋‹จ์— ๋Œ€ํ•ด ์•Œ์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—์ด ๋…ผ์˜์— ์ฐธ์—ฌ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ) _

๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋„๊ตฌ์—์„œ๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ทธ๋Ÿฌํ•œ ์•Œ๋ฆผ์„ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ๊ทธ๋Ÿฌํ•œ ์•Œ๋ฆผ์œผ๋กœ์ด ๊ฐ€์งœ ๋ฐฉ๋ฒ•์„ ์™„์ „ํžˆ ๋น„๋‚œํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ข‹์€ ์ƒ๊ฐ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฟก๋ฟก

๋˜ํ•œ unicode.org/reports/tr29๋ฅผ ์ฝ์—ˆ์„ ๋•Œ ์œ ๋‹ˆ ์ฝ”๋“œ ์‚ฌ์–‘์ด ์—ฌ๊ธฐ์— ๊ด€๋ จ์ด ์žˆ๋”๋ผ๋„ (์•„์ฃผ ์ž˜ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!) ๋งˆ์ง€๋ง‰ \ n๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์ด ๊ธˆ์ง€๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์‹  ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์–‘์„ ์ฝ์œผ๋ฉด์„œ CR | ร— | LF, ์—ฌ๊ธฐ์„œ ร—๋Š” "๊ฒฝ๊ณ„ ์—†์Œ (์—ฌ๊ธฐ์„œ๋Š” ๋Š๊ธฐ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Œ)"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹œํ€€์Šค๋ฅผ ๊นจ๋œจ๋ฆด ๋•Œ \ r \ n \ n ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ž์™€ ๋‘ ๋ฒˆ์งธ ๋ฌธ์ž ์‚ฌ์ด์— "๋ถ„๋ฆฌ"๋ฅผ ๋‘๋Š” ๊ฒƒ๋งŒ ๊ธˆ์ง€ํ•˜์ง€๋งŒ ์„ธ ๋ฒˆ์งธ ๋ฌธ์ž ์•ž์— "๋ถ„๋ฆฌ"๋ฅผ ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €๋Š” \ r \ n \ n ๋‘ ๊ฐœ์˜ ๋ถ„๋ฆฌ ๋œ "๋ฌธ์ž ์†Œ ํด๋Ÿฌ์Šคํ„ฐ"๋กœ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค.

๋งž์•„์š”. \r\n\n ๋Š” \r\n ๋ฐ \n ๋กœ 2 ๊ฐœ์˜ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  IndexOf๊ฐ€ ์ „์ฒด ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ์™€ ์ผ์น˜ํ•ด์•ผํ•˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ผ๋ถ€๋ฅผ ๋งŒ์ง€์ง€ ์•Š๋”๋ผ๋„ ๋ฌธ์ž์—ด \ n \ r \ nTest ๋‚ด๋ถ€์—์„œ ํ•˜์œ„ ๋ฌธ์ž์—ด \ nTest๋ฅผ ์ฐพ์•„์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ํ‹€ ๋ ธ์Šต๋‹ˆ๋‹ค. \n\r\nTest ๋Š” ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. \n , \r\n ๋ฐ Test . \nTest ๋Š”์ด ๋ฌธ์ž์—ด์˜ ์ผ๋ถ€๊ฐ€ ๋  ์ˆ˜ ์—†์Œ์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐ \r\n ๋ช‡ ๊ฐ€์ง€ ๊ธฐํ˜ธ X . ์ด์ œ ์†Œ์Šค ๋ฌธ์ž์—ด์€ \nXTest ํฌํ•จํ•˜์ง€ ์•Š๋Š” \nTest ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ICU ๋ฐ / ๋˜๋Š” ์œ ๋‹ˆ ์ฝ”๋“œ ์‚ฌ์–‘์— ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ ๋Ÿฐํƒ€์ž„ / ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€์ด ํŠน์ • ์˜ˆ์ œ์—์„œ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ด์•ผํ•œ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์ •๋ ฌ ๊ฐ•๋„ ์ˆ˜์ค€์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋Œ€๋‹ต์€ ์˜ˆ์ž…๋‹ˆ๋‹ค. ICU๋Š” ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜์žˆ๋Š” ๊ฐ•๋„ ์ˆ˜์ค€์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

CultureInfo.CurrentCulture.CompareInfo.IndexOf(actual, expected, CompareOptions.IgnoreSymbols)

๊ฐ•๋„ ์ˆ˜์ค€์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์ž‘์—…์—์„œ ๊ธฐํ˜ธ๋ฅผ ๋ฌด์‹œํ•˜๋„๋กํ•ฉ๋‹ˆ๋‹ค ( \n ๋ฐ \r ์€ ํ•ด๋‹น ์‹œ์ ์—์„œ ๋ฌด์‹œ๋˜๋ฏ€๋กœ ๋ณ€๊ฒฝ๋จ).

๋˜ํ•œ ์ˆœ์ˆ˜ ICU ๋„ค์ดํ‹ฐ๋ธŒ C ์•ฑ์„ ์ž‘์„ฑํ•˜๊ณ  ๋™์ผํ•œ ๊ฒฝ์šฐ๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

void SearchString(const char *target, int32_t targetLength, const char *source, int32_t sourceLength)
{
    static UChar usource[100];
    static UChar utarget[100];

    u_charsToUChars(source, usource, sourceLength);
    u_charsToUChars(target, utarget, targetLength);

    UErrorCode status = U_ZERO_ERROR;
    UStringSearch* pSearcher = usearch_open(utarget, targetLength, usource, sourceLength, "en_US", nullptr, &status);
    if (!U_SUCCESS(status))
    {
        printf("usearch_open failed with %d\n", status);
        return;
    }

    int32_t index = usearch_next(pSearcher, &status);
    if (!U_SUCCESS(status))
    {
        printf("usearch_next failed with %d\n", status);
        return;
    }

    printf("search result = %d\n", index);
    usearch_close(pSearcher);
}


int main()
{
    SearchString("\nT", 2, "\r\nT", 3);
    SearchString("\nT", 2, "\n\nT", 3);
}

์ด ์•ฑ์€ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

search result = -1
search result = 1

.NET์—์„œ ๋ณผ ์ˆ˜์žˆ๋Š” ๋™์ž‘๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ์€์ด ํŠน์ • \ r \ n ๋™์ž‘์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. IndexOf๊ฐ€์ด ํŠน์ • ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ ํ•  ๋•Œ "Grapheme Cluster Boundary Rules"๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• (๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผํ•˜๋Š”์ง€ ์—ฌ๋ถ€)์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ™•์‹คํžˆ ํด๋Ÿฌ์Šคํ„ฐ๋ง์ด ๋ฐ์ดํ„ฐ ์ •๋ ฌ ์ž‘์—…์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. http://unicode.org/reports/tr29/tr29-7.html ์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Grapheme clusters include, but are not limited to, combining character sequences such as (g + ยฐ), digraphs such as Slovak โ€œchโ€, and sequences with letter modifiers such as kw. Grapheme ํด๋Ÿฌ์Šคํ„ฐ ๊ฒฝ๊ณ„๋Š” ๋ฐ์ดํ„ฐ ์ •๋ ฌ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. , regular-expressions, and counting โ€œcharacterโ€ positions within text. Word boundaries, line boundaries and sentence boundaries do not occur within a grapheme cluster. In this section, the Unicode Standard provides a determination of where the default grapheme boundaries fall in a string of characters. This algorithm can be tailored for specific locales or other customizations, which is what is done in providing contracting characters in collation tailoring tables.

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ ํ•  ๋‚ด์šฉ์ด ๋” ์žˆ์œผ๋ฉด @GrabYourPitchforks์— ๋Œ“๊ธ€์„ ๋‹ฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋„๊ตฌ์—์„œ๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ทธ๋Ÿฌํ•œ ์•Œ๋ฆผ์„ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ๊ทธ๋Ÿฌํ•œ ์•Œ๋ฆผ์œผ๋กœ์ด ๊ฐ€์งœ ๋ฐฉ๋ฒ•์„ ์™„์ „ํžˆ ๋น„๋‚œํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ข‹์€ ์ƒ๊ฐ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌ!
์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค.

์ œ ์ž์‹ ์„ ์œ„ํ•ด ๋ฒ„์ „ ๊ฐ„์˜ ๋‹ค์–‘ํ•œ ๊ณผ๋ถ€ํ•˜๋ฅผ ๋น„๊ตํ–ˆ์Šต๋‹ˆ๋‹ค.

| ๋ฐฉ๋ฒ• | netcoreapp3.1 | net5.0 |
| ------------------------------------------------- --------------- | ----------------- | ---------- |
| actual.Contains(expected) | ์‚ฌ์‹ค | ์‚ฌ์‹ค |
| actual.IndexOf(expected) | 1475 | -1 |
| actual.Contains(expected, StringComparison.CurrentCulture) | ์‚ฌ์‹ค | ๊ฑฐ์ง“ |
| actual.IndexOf(expected, StringComparison.CurrentCulture) | 1475 | -1 |
| actual.Contains(expected, StringComparison.Ordinal) | ์‚ฌ์‹ค | ์‚ฌ์‹ค |
| actual.IndexOf(expected, StringComparison.Ordinal) | 1475 | 1475 |
| actual.Contains(expected, StringComparison.InvariantCulture) | ์‚ฌ์‹ค | ๊ฑฐ์ง“ |
| actual.IndexOf(expected, StringComparison.InvariantCulture) | 1475 | -1 |

์ด๋ฅผ ์œ„ํ•ด ๋ถ„์„๊ธฐ๋ฅผ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค.

์ด๊ฒƒ์€ ์žฅ๊ธฐ์ ์œผ๋กœ๋Š” ์ข‹์ง€๋งŒ .NET 5๊ฐ€ ์ถœ์‹œ๋˜๋ฉด ์—„์ฒญ๋‚œ ์–‘์˜ ์ดํƒˆ์„ ์ผ์œผํ‚ค๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ค‘ ํ•˜๋‚˜ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์ด .NET 5์™€ .NET Core 3.1๊ฐ„์— ๋‹ค๋ฅธ ๊ฒฝ์šฐ .NET 5๊ฐ€ ์ „๋‹ฌ ๋œ string ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” .NET Standard 2.0 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์— ์ •์˜ ๋œ ๊ฐœ์ฒด๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๊นŒ? .NET callsite์—์„œ? ์ด์ „ ๋™์ž‘์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์ƒˆ๋กœ์šด ๋™์ž‘์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๊นŒ?

@Aaronontheweb ์ƒˆ๋กœ์šด ํ–‰๋™. ์ฒ˜์Œ์—๋Š” netstandard2.0 ๋ฅผ ๋ชฉํ‘œ๋กœํ•˜๋Š” NUnit3์˜ ์–ด์„ค ์…˜์—์„œ ์ด๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์—…๊ทธ๋ ˆ์ด๋“œ ํ›„ ๋Œ€์ƒ ํ”„๋ ˆ์ž„ ์›Œํฌ ๋งŒ ๋ณ€๊ฒฝํ–ˆ์„ ๋•Œ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋Œ€๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค-๋‚ด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์˜ค๋ž˜๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์›ํ•  ๋•Œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์„ ์ œ์–ด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‹จ์œ„ ํ…Œ์ŠคํŠธ์—์„œ์ด๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•˜๊ณ  ํ”„๋กœ๋•์…˜์— ์ ์šฉํ•˜์ง€ ์•Š๋Š” ์•ฑ์€ ๋ช‡ ๊ฐœ์ž…๋‹ˆ๊นŒ?
.NET ํŒ€์€ ์ด๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜์žˆ๋Š” ๊ณ ํ†ต๊ณผ ๋ฌธ์ œ์  ๋ฐ ๋น„์šฉ์„ ๊ณ ๋ ค ํ–ˆ์Šต๋‹ˆ๊นŒ?

๊ทธ๊ฒƒ์€ ๋Œ€๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค-๋‚ด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์˜ค๋ž˜๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์›ํ•  ๋•Œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์„ ์ œ์–ด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฉ‹์ง„ ํ•จ์ •!
์ด์ƒํ•œ ๋ฒŒ๋ ˆ๋ฅผ ์‚ฌ๋ƒฅํ•˜๋ฉฐ ๋‚ญ๋น„ํ•˜๋Š” ํ–‰๋ณตํ•œ ์‹œ๊ฐ„ ๐ŸŽ‰
ํ•˜์ง€๋งŒ InvariantGlobalization์ด์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด๋ฅผ ์œ„ํ•ด ๋ถ„์„๊ธฐ๋ฅผ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค.

๋„ค. ๊ทธ๋ฆฌ๊ณ  F # ์ง€์›์„ ์žŠ์ง€ ๋งˆ์„ธ์š”.

๋‹จ์œ„ ํ…Œ์ŠคํŠธ์—์„œ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•˜๋Š” ์•ฑ ์ˆ˜

0-๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” .NET BCL ์ž์ฒด์™€ ๊ฐ™์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ / ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚ด ๊ฒฌํ•ด๋Š”์ด ๋™์ž‘ ๋ณ€๊ฒฝ ๋ชจ๋“œ๋ฅผ ์ œ์–ด ํ•  ์ˆ˜์žˆ๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ ๋ ˆ๋ฒจ ์†์„ฑ์ด ์žˆ์–ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์–ด์…ˆ๋ธ”๋ฆฌ ๋ณ„ ์ˆ˜์ค€์—์„œ ์˜ตํŠธ ์ธ / ์˜ตํŠธ ์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ .NET Standard ๋ฌธ์ œ๋„ ์‚ฌ๋ผ์ง์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋Œ€๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค-๋‚ด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์˜ค๋ž˜๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์›ํ•  ๋•Œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์„ ์ œ์–ด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์™œ ๋‹น์‹ ์ด ๊ทธ๊ฒƒ์„ ํ†ต์ œ ํ•  ์ˆ˜ ์—†๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ฌธ์ž์—ด ๋น„๊ต๋Š” ICU ๋˜๋Š” NLS๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ compat ์Šค์œ„์น˜๋ฅผ ์‚ฌ์šฉ

์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€๋˜๋Š” ์„ธ๊ณ„ํ™” ๋ฐ์ดํ„ฐ์— ์˜์กด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ์„ธ๊ณ„ํ™” ๋ฐ์ดํ„ฐ์— ์˜์กดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋ง๊ฐ€ ๋œจ๋ฆฌ๋Š” ๊ฒƒ์„ ๋‘๋ ค์›Œํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” Windows ํŒ€์˜ ์˜๊ฒฌ์„ ๋“ค์–ด๋ณด์‹ญ์‹œ์˜ค. ์„ธ๊ณ„ํ™” ๊ธฐ๋Šฅ์€ ๋ธ”๋ž™ ๋ฐ•์Šค ์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (ํŠนํžˆ .NET Standard๋ฅผ ๋Œ€์ƒ์œผ๋กœํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๊ฐ€ ์ด์™€ ๊ฐ™์€ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์— ์˜์กดํ•œ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์€ ์ด์น˜์— ๋งž์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด Windows์™€ Linux์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” .NET ์„ธ๊ณ„ํ™” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋ถˆํ‰ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. Windows์™€ ๋‹ค๋ฅธ ํ”Œ๋žซํผ ๊ฐ„์˜ ๋™์ž‘์„ ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚ซ์Šต๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ์ฝ”๋“œ๋Š” ์„ธ๊ณ„ํ™” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถˆ๋ณ€์— ์˜์กดํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.

StringComparison.Ordinal ๋„ ๊ธฐ๋ณธ ๋น„๊ต ์ „๋žต์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€๋ฅผ ๊ณ ๋ ค ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์„ธ๊ณ„ํ™”๊ฐ€ ๋งค์šฐ ๋ถˆ์•ˆ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์–ด๋„ ๊ธฐ๋ณธ ๊ตฌํ˜„์ด ์•ˆ์ •์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. string.Equals(...) ๋˜๋Š” string.Contains(...) ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค ์ค‘ StringComparison ๋ฅผ ํ†ต๊ณผํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๋Š” 99.9 %์˜ ์‚ฌ๋žŒ๋“ค์ด ๋กœ์ผ€์ผ.

ํŽธ์ง‘ : ๋‚ด ์งˆ๋ฌธ์— ์ด๋ฏธ ๋‹ต๋ณ€ ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ์šฐ๋ฆฌ๋Š” ์ด์ „์— Silverlight ๋ฆด๋ฆฌ์Šค ์ค‘์— ์„œ์ˆ˜ ๋™์ž‘์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์—๋ณด๊ณ  ๋œ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ IndexOf์™€ ๊ฐ™์€ ๊ฒƒ์„ ํ˜ธ์ถœ ํ•  ๋•Œ ์˜์‹์„ ๊ฐ–๊ณ  ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ StringComparison ํ”Œ๋ž˜๊ทธ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋” ๋งŽ์€ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์ด ์ƒ๊ฐ ํ•ด๋‚ผ ์ˆ˜์žˆ๋Š” ๋ชจ๋“  ์•„์ด๋””์–ด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

์›ํ•˜๋Š” ๊ฒฝ์šฐ compat ์Šค์œ„์น˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ICU๋ฅผ ์˜ตํŠธ ์•„์›ƒ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ด์ „ ๋™์ž‘์œผ๋กœ ๋˜๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.

์ €๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์•„๋‹Œ ์ƒ๊ณ„๋ฅผ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์€ InvariantCulture ์ด๋ฉฐ, ์ œ๊ฐ€ ์ด์ „์— ์ดํ•ด ํ•œ ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์„ค๊ณ„ ์ƒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ๋„ IndexOf ์˜ ๋™์ž‘์ด .NET 5.0๊ณผ .NET Core 3.1๊ฐ„์— ๋‹ค๋ฅธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ถ„์„๊ธฐ๊ฐ€ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์–ด๋–ค ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@petarrepac ๋„ C # ์ „์šฉ์ž…๋‹ˆ๋‹ค.

@isaacabraham ๊ณผ VB๋„;)

๋‚˜๋Š” ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

@Aaronontheweb ๋‹น์‹ ์€ ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค (์•ฑ์„ ์ปดํŒŒ์ผ ํ•  ๋•Œ). ์ด๊ฒƒ์„ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>

ํŽธ์ง‘ : ์ด๊ฒƒ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์—๋งŒ ํ•ด๋‹น๋˜๋ฉฐ, ๋ถˆํ–‰ํžˆ๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ์ด๋ฅผ ์ œ์–ด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์žฅ๊ธฐ์ ์œผ๋กœ Windows ํŒ€์€ ICU ๋กœ์˜ ์ด์ „์„ ์ถ”์ง„ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์–ด๋Š ์‹œ์ ์—์„œ ICU๋Š” ์„ธ๊ณ„ํ™” ์Šคํ† ๋ฆฌ๊ฐ€ ๋  ๊ฒƒ์ด๋ฉฐ ์šฐ๋ฆฌ๋Š” OS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‘˜๋Ÿฌ์‹ผ ์–‡์€ ๋ž˜ํผ ์ผ๋ฟ์ž…๋‹ˆ๋‹ค.

.NET 5๊ฐ€ .NET ํ˜ธ์ถœ ์‚ฌ์ดํŠธ์—์„œ ์ „๋‹ฌ ๋œ ๋ฌธ์ž์—ด์„ ์กฐ์ž‘ํ•˜๋Š” .NET Standard 2.0 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์— ์ •์˜ ๋œ ๊ฐœ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ป๊ฒŒ๋ฉ๋‹ˆ๊นŒ? ์ด์ „ ๋™์ž‘์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์ƒˆ๋กœ์šด ๋™์ž‘์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๊นŒ?

์ƒˆ๋กœ์šด ๋™์ž‘์€ ๋Ÿฐํƒ€์ž„์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋ฉฐ .NET Standard๋Š” ๋Ÿฐํƒ€์ž„์„ ๊ตฌํ˜„ํ•˜๊ธฐ์œ„ํ•œ ํ‘œ์ค€ ์ผ ๋ฟ์ด๋ฏ€๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด Unix์™€ Windows๊ฐ„์— ํ”Œ๋žซํผ ์ผ๊ด€์„ฑ์„ ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค. ์‚ฌ๋žŒ๋“ค์ด Unix์—์„œ ์šฐ๋ คํ•˜๋Š” ๋™์ผํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ICU ๊ฐ€ ๋ฐฑ์—…์ด๋ฏ€๋กœ ICU ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Unix์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ.

@reflectronic ์€ https://github.com/dotnet/runtime/issues/43736#issuecomment -716681586์˜ ๋ชจ๋“  ์ ์—์„œ ์˜ณ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ https://github.com/dotnet/runtime/issues/43736#issuecomment -716527590์— ์–ธ๊ธ‰ ๋œ @jbogard ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด ์˜๊ฒฌ์„ ๋งํ•˜๋ ค๋ฉด Windows์™€ ICU ๊ฐ„์˜ ์–ธ์–ด ๋™์ž‘์„ ๋น„๊ตํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์š”์•ฝํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค. ๋ง๋ถ™์—ฌ์„œ ํ˜„์žฌ ICU๋Š” Windows์˜ ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๋Š” .NET Core 3.1 ์ดํ•˜๊ฐ€ ์„ค์น˜๋œ Linux๋ฅผ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” .NET 5.0๊ณผ Linux์˜ ์ด์ „ ๋ฒ„์ „ ๊ฐ„์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ž‘๋™ํ•˜๋˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์š”์ ์€ ๊นจ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ด๋ฏธ Linux์—์„œ ์†์ƒ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์™„์ „ํžˆ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค.

StringComparison.Ordinal์„ ๊ธฐ๋ณธ ๋น„๊ต ์ „๋žต์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋ธŒ๋ ˆ์ดํ‚น ๋ณ€๊ฒฝ์„ ๊ณ ๋ ค ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์•ž์„œ ๋ง์”€ ๋“œ๋ ธ์ง€๋งŒ ์ด๋ฏธ ์‹œ๋„ํ•ด ๋ณด์•˜์ง€๋งŒ ๋ถˆ๋งŒ์˜ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ์ปค์„œ ์ ์šฉ ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฐ์ดํ„ฐ ์ •๋ ฌ API๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ ๋ฌธ์ž์—ด ๋น„๊ต ํ”Œ๋ž˜๊ทธ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ ์˜์‹ํ•˜๋Š” ๋ฐ ๋„์›€์ด๋˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์•„๋‹Œ ์ƒ๊ณ„๋ฅผ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์ผ๋ถ€ ๋ถ„์„๊ธฐ๊ฐ€ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ •๋ ฌ API ํ˜ธ์ถœ์„๋ณด๊ณ  ์„œ์ˆ˜ ๋˜๋Š” ์–ธ์–ด ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์˜๋„๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๋ถ„์„๊ธฐ๊ฐ€ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์–ด๋–ค ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ถ„์„๊ธฐ๋Š” ์ฝ”๋“œ๋ฅผ ์Šค์บ”ํ•˜๊ณ  ํ”Œ๋ž˜๊ทธ๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ ์ •๋ ฌ API ํ˜ธ์ถœ์„ ๊ฐ์ง€ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์„ ์‚ดํŽด๋ณด๊ณ  ๋ฌธ์ œ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด๋ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋˜ํ•œ C # ์ „์šฉ์ž…๋‹ˆ๋‹ค.

๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ „์—ญ ์ ์ด์–ด์•ผํ•˜๋ฉฐ C #์œผ๋กœ ์ œํ•œ๋˜์ง€ ์•Š๋Š” .NET ๋Ÿฐํƒ€์ž„ ๋‚ด๋ถ€์— ์žˆ์Šต๋‹ˆ๋‹ค.

@tarekgh C # ๋ถ„์„๊ธฐ๋Š” VB ๋˜๋Š” F # ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์–ด๋–ป๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๊ฐ€ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์€ InvariantCulture ์ด๋ฉฐ, ์ œ๊ฐ€ ์ด์ „์— ์ดํ•ด ํ•œ ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์„ค๊ณ„ ์ƒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋น„ํŒ์ ์œผ๋กœ,์ด ๋ณ€๊ฒฝ ์ด์ „์—๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ฝ”๋“œ์— ๋Œ€ํ•ด ์‹ค์ œ๋กœ ์ด๊ฒƒ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. NLS์™€ ICU์˜ ๋™์ž‘ ๋ฐฉ์‹์€ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ ํ•ญ์ƒ ๋™์ผํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค (์ด ๋ฌธ์ œ์—์„œ ์ž…์ฆ ๋จ). @tarekgh๊ฐ€ ๋งํ–ˆ๋“ฏ์ด์ด ์ฝ”๋“œ๋Š” Linux์—์„œ ๊ณ„์† ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ ์šฉ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ์ตœ์‹  Windows ์„ค์น˜์— ๋Œ€ํ•ด "๋ถˆ๋ณ€ ๋ฌธํ™”"๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š” ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ _ ์‹ค์ œ๋กœ _ ์ผ๊ด€์„ฑ์ด ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋†€๋ผ์šด ์ผ์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‹ค๋ฅธ ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์ˆ˜๋…„ ๋™์•ˆ ํ•ด์™” ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž๋ณด๊ณ ์˜ ๊ฒฐ๊ณผ๋กœ ์ˆ˜๋…„ ๋™์•ˆ ํ”Œ๋žซํผ ์ฐจ์ด์™€ ๊ด€๋ จ๋œ ์ˆ˜์‹ญ ๊ฐœ์˜ ๋ฒ„๊ทธ๋ฅผ ์ฐพ์•„ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

.NET 5๊ฐ€ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์ƒˆ๋กœ์šด ์ž‘๋ฌผ์„ ๋„์ž…ํ•˜๊ณ  ๋‚ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์šด ์ŠคํŠธ๋ฆผ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์„ ๋‹ค์‹œ ๊ฒ€ํ†  ํ•  ๊ฒƒ์ด๋ผ๋Š” ์ „๋ง์— ํฅ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ƒˆ๋กœ์šด ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ์„ ๊ฐ€์ ธ ์˜ค์ง€ ์•Š๋Š” ์ƒ๋‹นํ•œ ๊ฒฝ์ œ์  ๋น„์šฉ์ž…๋‹ˆ๋‹ค. MSFT์˜ ๋ˆ„๊ตฐ๊ฐ€๋Š” ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ๋น„์šฉ / ํŽธ์ต ๋…ผ์˜์—์„œ์ด๋ฅผ ๊ณ ๋ คํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘ : ์ด๋ฏธ ๊ธฐ์ˆ ์  ์ธ ์žฅ์ ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค-์˜ˆ, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋น„์šฉ์ด ์•„๋‹Œ ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ๋ช…๋ฐฑํ•˜์ง€ ์•Š์€ ๊ฒฝ์ œ์  ์ด์ต์„ ํŒ๋งคํ•˜๋„๋ก ๋„์™€์ฃผ์„ธ์š”. ์ด ๋ฌธ์ œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ๊ณ ๋ คํ•  ๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ ๋„์•ฝํ•˜๊ณ  .NET 5๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์•ผํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@tarekgh C # ๋ถ„์„๊ธฐ๋Š” VB ๋˜๋Š” F # ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์–ด๋–ป๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๊นŒ?

๋‹จ์ผ ๋ถ„์„๊ธฐ๋กœ C # ๋ฐ VB๋ฅผ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ โ€‹โ€‹์žˆ์ง€๋งŒ (๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๋ถ„์„๊ธฐ๋ฅผ ์–ธ์–ด์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค) ํ˜„์žฌ F #์— ๋Œ€ํ•œ ๋ถ„์„๊ธฐ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@Aaronontheweb ๋ฌธํ™”์  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์€ ICU ๋ณ€๊ฒฝ์„ํ•˜์ง€ ์•Š์•˜๋”๋ผ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. Windows ํŒ€์˜ https://docs.microsoft.com/en-us/archive/blogs/shawnste/locale-culture-data-churn ๋ธ”๋กœ๊ทธ์—์„œ NLS ๋™์ž‘๋„ ๊ฐœ์„ ์„ ์œ„ํ•ด ๋ณ€๊ฒฝ๋˜๊ณ  ์žˆ์Œ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” ์•ฑ / ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€์ ์—์„œ ์ž˜๋ชป๋œ ๊ฐ€์ •์„ ํฌ์ฐฉํ•˜๋Š” ๊ฒƒ ์ด์ƒ์œผ๋กœ ICU๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. 5.0์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์€ ๋‹ค๋ฅธ ์ด์ „ ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์€ ์ƒˆ๋กญ๊ณ  ๋ฉ‹์ง„ ๊ธฐ๋Šฅ์„ ๋งŽ์ด ๊ฐ–๊ฒŒ ๋  ๊ฒƒ์ด๋ฉฐ ์•ฑ์€ ๋ฆด๋ฆฌ์Šค ์‚ฌ์ด์— ๋ช‡ ๊ฐ€์ง€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ…Œ์ŠคํŠธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์„ธ๊ณ„ํ™”๊ฐ€ OS์™€ OS ๋ฒ„์ „ ์‚ฌ์ด์—์„œ ์–ธ์ œ๋“ ์ง€ ๋ฐ”๋€” ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ธ๊ณ„ํ™” ๋™์ž‘ ๋ณ€ํ™”๊ฐ€ ์ •๋ง๋กœ ๊นจ์ง€๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด NLS๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜์—ฌ 5.0์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋„๋ก ์„ ํƒํ•  ์ˆ˜์žˆ๋Š” ๊ตฌ์„ฑ ์Šค์œ„์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ICU๋Š” ์‹ค์ œ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฒฐ์ •์˜ ์š”์†Œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด์ œ ICU๋ฅผ ํ†ตํ•ด ์•ฑ์€ OS ์ „๋ฐ˜์— ๊ฑธ์ณ ์ผ๊ด€์„ฑ์„ ๋†’์ผ ์ˆ˜์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ๊ฐ–๊ฒŒ๋˜๋ฉฐ ์•ฑ ๋กœ์ปฌ ICU๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ๊ฒฝ์šฐ ์„ธ๊ณ„ํ™” ๋™์ž‘์„ ๋” ๋งŽ์ด ์ œ์–ด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด์ „๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ์ œ์–ด๊ถŒ์„ ์•ฑ์— ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ : https://github.com/dotnet/runtime/issues/43802

(์ด ๋ฌธ์ œ๋Š” IndexOf _per se_๋ฅผ ์ถ”์ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜คํžˆ๋ ค ๋ฌธํ™” ์ธ์‹ ๋น„๊ต์ž๋ฅผ ๊ธฐ๋ณธ์œผ๋กœํ•˜๋Š” Compare ๋ฃจํ‹ด์˜ ์˜๋„ํ•˜์ง€ ์•Š์€ ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.)

๋ถ„์„๊ธฐ๊ฐ€ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์–ด๋–ค ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ถ„์„๊ธฐ๋Š” ์ฝ”๋“œ๋ฅผ ์Šค์บ”ํ•˜๊ณ  ํ”Œ๋ž˜๊ทธ๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ ์ •๋ ฌ API ํ˜ธ์ถœ์„ ๊ฐ์ง€ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์„ ์‚ดํŽด๋ณด๊ณ  ๋ฌธ์ œ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด๋ฉ๋‹ˆ๋‹ค.

csproj์— ๋ถ„์„๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ์ž๋™์œผ๋กœ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋งŽ์€ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ๊ฐ€ ์ด๋Ÿฌํ•œ ๋ถ„์„๊ธฐ์—†์ด .NET 5๋กœ ์ด๋™ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋˜ํ•œ ์ด๋ฏธ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด F # ํ”„๋กœ์ ํŠธ์—๋Š” ๋„์›€์ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@jeffhandley ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, ๋‚ด๊ฐ€ ์ด๋ฏธ ์ดํ•ด ํ•œ ๊ฒƒ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ€๋Šฅํ•œ "ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•"์ด F # ์‚ฌ์šฉ์ž์—๊ฒŒ ๋„์›€์ด๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ธ์‹ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค (์ž‘์€ ์‹œ์žฅ์ด์ง€๋งŒ .NET์˜ ์ผ๋ฅ˜ ์‹œ๋ฏผ์œผ๋กœ์„œ MS์—์„œ ์™„์ „ํžˆ ์ง€์›ํ•˜๋Š” ์‹œ์žฅ). ์ด๊ฒƒ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ „์—ญ ์ ์ด์–ด์•ผํ•˜๋ฉฐ C #์œผ๋กœ ์ œํ•œ๋˜์ง€ ์•Š๋Š” .NET ๋Ÿฐํƒ€์ž„ ๋‚ด๋ถ€์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.
๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ „์—ญ ์ ์ด์–ด์•ผํ•˜๋ฉฐ C #์œผ๋กœ ์ œํ•œ๋˜์ง€ ์•Š๋Š” .NET ๋Ÿฐํƒ€์ž„ ๋‚ด๋ถ€์— ์žˆ์Šต๋‹ˆ๋‹ค.

.NET ๋Ÿฐํƒ€์ž„์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์–ธ์–ด๊ฐ€ C #๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์˜ํ–ฅ์„๋ฐ›์„ ๊ฒƒ์ž„์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํŠนํžˆ ๊ณ„ํš์ด ํ˜„์žฌ ํ–‰๋™์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด๋ผ๋ฉด ์ƒˆ๋กœ์šด ์„ธ๊ณ„์—์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌ ํ•  ๋ถ„์„๊ธฐ๊ฐ€ ์žˆ์–ด์•ผํ•œ๋‹ค๋Š” ๋‚ด ์˜๊ฒฌ์„ ๋‹ค์‹œ ๊ฐ•ํ•˜๊ฒŒ ๋งํ•  ๊ฒƒ์ด๋‹ค.

๋‚˜๋Š” ๊ทธ๋ ‡๊ฒŒํ•˜๋Š” ๊ฒƒ์˜ ๊ธฐ์ˆ ์  ์žฅ์ ์„ ์™„์ „ํžˆ ์ดํ•ดํ•˜๋ฉฐ ๋ณ€๊ฒฝํ•˜์ง€ ๋ง๋ผ๊ณ  ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค (์žฅ๊ธฐ์ ์œผ๋กœ ์ด๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ์กฐ์น˜ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค). ์ด๋ฏธ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋กœ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ๋„ ์•„๋‹™๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ•˜๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ .NET 5๋กœ ์˜ฎ๊ธฐ๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์ด๊ฒƒ์ด ์ •๋ง๋กœ ํฌ๊ณ , ๋นจ๊ฐ„์ƒ‰์ด๊ณ , ๊นœ๋ฐ•์ด๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰์‹œ ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๊ฒƒ์ด "๊ทธ๋ƒฅ ์ž‘๋™ํ•œ๋‹ค"๊ณ  ๊ฐ€์ • ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ @meziantou ์˜์ด Roslyn ๋ถ„์„๊ธฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ https://github.com/meziantou/Meziantou.Analyzer/tree/master/docs.

์ด ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ MA0074๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค-์•”์‹œ ์  ๋ฌธํ™”์— ๋ฏผ๊ฐํ•œ ๋ฐฉ๋ฒ•์„ ํ”ผํ•˜์‹ญ์‹œ์˜ค

image

์ด๊ฒƒ์€ ์ •๋ง๋กœ ์ƒ์ž์—์„œ ๋ฒ—์–ด๋‚œ ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ๋งํ•˜๋ฉด์„œ ์—ฌ๊ธฐ ์—์ด Roslyn ๋ฌธ์ œ๋ฅผ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค .https : //github.com/dotnet/roslyn-analyzers/issues/4367

@tarekgh ๋ช…ํ™•ํžˆ

์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ IndexOf์™€ ๊ฐ™์€ ๊ฒƒ์„ ํ˜ธ์ถœ ํ•  ๋•Œ ์˜์‹์„ ๊ฐ–๊ณ  ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ StringComparison ํ”Œ๋ž˜๊ทธ๋ฅผ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋” ๋งŽ์€ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์ด ์ƒ๊ฐ ํ•ด๋‚ผ ์ˆ˜์žˆ๋Š” ๋ชจ๋“  ์•„์ด๋””์–ด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

[Obsolete] ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ๋ฉ”์†Œ๋“œ๋ฅผ ํ๊ธฐํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

API ํ‘œ๋ฉด์€ ๋™์ผํ•˜์ง€๋งŒ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜๋ฉด .NET Standard ํ˜ธํ™˜์„ฑ์€ ์–ด๋–ป๊ฒŒ๋ฉ๋‹ˆ๊นŒ?

๊ทธ๋ž˜ ์†Œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์กด์ค‘ํ•˜๊ธฐ์œ„ํ•œ ๋ณ€๊ฒฝ์€ ์˜ํ–ฅ์ด ์ž˜ ๋ฌธ์„œํ™”๋˜์–ด์žˆ๋Š” ํ•œ ๋‚˜๋ฅผ ๊ดด๋กญํžˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ด€๋ จ๋œ ๋ฌธ์ž์—ด ๋ฉ”์„œ๋“œ ํŒจ๋ฐ€๋ฆฌ ๊ตฌ์„ฑ์›์ด ์„œ๋กœ ์ผ๊ด€๋˜์ง€ ์•Š๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ž, ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ ๋˜๋Š” ๋กœ์ผ€์ผ์˜ ๋ชจํ˜ธํ•จ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋น„๊ณต์‹์  ์ธ ๋ฌธ์ž์—ด ๋ญ‰ํ‚น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ์€ str.Contains (whatever)๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด str.IndexOf (whatever ) ์šฐ๋ฆฌ๋Š” ๋ฐฉ๊ธˆ ๊ทธ๊ฒƒ์ด ๊ฑฐ๊ธฐ์— ์žˆ๊ณ  ๋”ฐ๋ผ์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ธ์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ ๋ฉ”์†Œ๋“œ๊ฐ„์— ๋™์ผ ํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฏธ๋ฌ˜ํ•จ์„ ์—ฐ๊ตฌ ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ๋ถˆ์ผ์น˜๋Š” ์ „๋ฌธ๊ฐ€ ๋งŒ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ์–ธ์–ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฝ”๋“œ ์บ ํ”„์—์„œ ๋‚˜์˜ค๋Š” ์‚ฌ๋žŒ๋“ค์„ ์†Œ์™ธ์‹œํ‚ต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์‹์œผ๋กœ ์ง„์ž…ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ์ค€์„ ๋†’์ด ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

@lupestro์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ๋™์ž‘์˜ ๋ถˆ์ผ์น˜๋Š” ๋งค์šฐ ์šฐ๋ ค๋ฉ๋‹ˆ๋‹ค. ์˜ค๋ž˜ ์ง€์†๋˜๋Š” ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฅด๊ฒŒ ํ–‰๋™ํ•˜๊ณ  ์ผ๊ด€๋˜์ง€ ์•Š๊ฒŒ ํ–‰๋™ํ•œ๋‹ค๋ฉด ๋งŽ์€ ์Šฌํ””์ด์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ ์ด๊ฒƒ์— ๋ถ€๋”ช ํžˆ๊ณ  API์— ๋ฐฐ์‹ ๊ฐ์„ ๋Š๋ผ๊ณ  ๋‹ค๋ฅธ ์‹œ๊ฐ„ ํญํƒ„์ด ํญ๋ฐœํ•˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ ์žˆ๋Š” ๊ฒƒ์„ ๊ถ๊ธˆํ•ด ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด .NET ์ž…์–‘ ์ž๋“ค์ด ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ๋ฌธ์ œ์— ๋Œ€ํ•ด C #์„ ์“ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋กœ์ผ€์ผ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ์˜ค๋ฒ„๋กœ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ๋ฉ”์„œ๋“œ์˜ ๊ธฐ๋ณธ ๋กœ์ผ€์ผ์„ ์ •๊ทœํ™”ํ•ด์•ผํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ Compare ๋ฐ CompareOrdinal์ด ์žˆ์œผ๋ฉฐ (Last) IndexOf (Any) ๋ฐ (Last) IndexOf (Any) Ordinal์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ํ•ด๊ฒฐ์ฑ…์„ ์ข‹์•„ํ•˜์ง€ ์•Š์ง€๋งŒ ์ ์–ด๋„ ํ˜„์žฌ ์กด์žฌํ•˜๋Š” ๊ฒƒ๊ณผ ์ผ์น˜ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋ฌธ์ž์—ด์—์„œ ์„œ์ˆ˜ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋Š” ๊ฐ๊ฐ€ ์ƒ๊ฐ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋น ๋ฅด๊ฑฐ๋‚˜ ์˜ณ์€ ๊ฒƒ์„ ์„ ํƒํ•ด์•ผํ•œ๋‹ค๋ฉด ๋งค๋ฒˆ '์˜ณ์€'์„ ์„ ํƒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ผ๊ด€๋˜์ง€ ์•Š๊ณ  ์ง๊ด€์ ์ด์ง€ ์•Š์€ ํ–‰๋™์€ ๋งค์šฐ ์‹ค๋ง ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์ด๋ฏธ ์ข…๊ฒฐ๋˜์—ˆ์œผ๋ฏ€๋กœ .NET 5.0์—์„œ ์•ž์œผ๋กœ ๋‚˜์•„๊ฐˆ ๊ฒƒ์ด๋ผ๊ณ  ์ด๋ฏธ ๊ฒฐ์ •ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌผ๊ฑด์€ ์–ด๋ ต๊ณ  ๋ฌธํ™” (์‹œ๊ฐ„๊ณผ ๊ฐ™์€) ์ •๋ณด๋Š” ๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋น„ ๊ธฐ์ˆ ์  ์ธ ์ด์œ ๋กœ ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š”์ด๋ฅผ ์ธ์‹ํ•ด์•ผํ•˜์ง€๋งŒ ์ž์ฒด ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋ ค๋ฉด API์— ์˜์กดํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” @aolszowka ๊ฐ€ ์ง€์ ํ•œ ๊ฒฝ๊ณ  (5.0์—์„œ)๊ฐ€ ์žˆ์–ด์•ผํ•˜๋ฉฐ ๋” ์ค‘์š”ํ•œ ๊ฒƒ์€ ๋ฌธ์ œ์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋ฉฐ ๋•Œ๋กœ๋Š” ์˜ค๋ž˜๋œ ํ–‰๋™ / ๊ฐ€์ •์„ "ํŒŒ๊ดด"ํ•ด์•ผํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ์ƒˆ๋กœ์šด ๋ถˆ์ผ์น˜๊ฐ€ ๋„์ž…๋˜์–ด์•ผ ํ•จ์„ ์˜๋ฏธํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ์€ ์ฝ”๋“œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ธฐ๋Œ€์น˜๋ฅผ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ๋„์ค‘์— ๋‚ด ์ฝ”๋“œ๋ฅผ ๋‚ ๋ ค ๋ฒ„๋ฆฌ๋Š” ์ง๊ด€์ ์ด์ง€ ์•Š์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด์žˆ๋Š” ๊ฒƒ๋ณด๋‹ค CultureInfo๋ฅผ ๋ช…์‹œ ์ ์œผ๋กœ ์ง€์ • (ํ™•์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ โ€‹โ€‹์žˆ์Œ)ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ŠคํŠธ๋ ˆ์Šค๊ฐ€ ๋งŽ์€ ๊ฐœ๋ฐœ์ฃผ๊ธฐ ๋˜๋Š” ์ตœ์•…์˜ ๊ณ ๊ฐ ์„ค์น˜.

TLDR : ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ์‚ฌํ•ญ์„ ๋ณ€๊ฒฝํ•˜์ง€๋งŒ API์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๋ถ€์ˆ˜๋ ค๋ฉด ๋” ๋‚˜์€ ๊ฒƒ์œผ๋กœ ๊ต์ฒดํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ์ˆ˜๋…„๊ฐ„ .NET์„ ์‚ฌ์šฉํ•ด ์™”์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ ํ•ญ์ƒ InvariantCulture๋กœ ๊ธฐ๋ณธ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜์–ด ์ด์™ธ์˜ ์–ธ์–ด์™€ ๊ด€๋ จํ•˜์—ฌ ์ €๋Š” ํ•ญ์ƒ ๋‹ค๋ฅธ ์–ธ์–ด ๋ณ„ ๋ฌธ์ž์˜ ๋ณ„์นญ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๋ฌธ์ž ์Œ๊ณผ CurrentCulture๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋น„๊ตํ•  ๋•Œ ์ด๋Ÿฌํ•œ ์Œ์„ ํ™•์ธํ•˜๋Š” ์ถ”๊ฐ€ ์ž‘์—…์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณด๋‚ธ ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํ˜ธํ•˜๋Š” ์–ธ์–ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์Šค๋ ˆ๋“œ์˜ CurrentCulture๋ฅผ ์„ค์ •ํ•˜๋Š” ASP.NET ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ด๋กœ ์ธํ•ด ์ €๋ฅผ ๋ฌผ์—ˆ๊ณ , ์˜์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๋น„๊ต๋Š” ์ฝ”๋“œ๋ฅผ ๋ฏธ๋ฌ˜ํ•˜๊ฒŒ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฌธ์ž์—ด์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ ํ•œ (์–ธ์–ด) ํ…์ŠคํŠธ์™€ ์„œ์ˆ˜ ํ…์ŠคํŠธ๊ฐ€ ํ˜ผํ•ฉ ๋œ ๊ฒฝ์šฐ

์ด ์œ ๋‹ˆ ์ฝ”๋“œ grapheme ํด๋Ÿฌ์Šคํ„ฐ ๋™์ž‘์€ ๋‚ด๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Invariant ์˜ค๋ฒ„๋กœ๋“œ๋ฅผ ์‚ฌ์šฉ ํ–ˆ๋”๋ผ๋„ ์ค„ ๋ฐ”๊ฟˆ ๋ฐ ์บ๋ฆฌ์ง€ ๋ฆฌํ„ด์— ๋Œ€ํ•œ ์„œ์ˆ˜ ๋™์ž‘์„ ์˜ˆ์ƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์—๊ฒŒ ์ƒˆ๋กœ์šด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ•˜๊ณ  ์ „๋ฌธ ์ง€์‹ ์ด

์˜ค๋ž˜๋œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ๊ณ ๋ คํ•˜๊ณ ์žˆ๋Š” ํ•œ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์–ด์ œ ๋ฐค์— ์ œ์•ˆ ์ดˆ์•ˆ์„ ์ž‘์„ฑํ•˜๊ณ  ๋‚ด๋ถ€ ๊ฒ€ํ† ๋ฅผ ์œ„ํ•ด ์‡ผํ•‘ ์ค‘์ด๋ฉฐ ๋ช‡ ์‹œ๊ฐ„ ํ›„์— ์—ฌ๊ธฐ์— ์ƒˆ ๋ฌธ์ œ๋กœ ๊ฒŒ์‹œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ดˆ์•ˆ์€ https://github.com/dotnet/runtime/issues/43956์— ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค

๋ฒ„๊ทธ๋ฅผ๋ณด๊ณ ํ•˜๋Š” ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ•˜๊ณ  ํ•ด๋‹น ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„๊ทธ๋ฅผ ์„ค๋ช…ํ•˜์‹ญ์‹œ์˜ค.

์ด ํŠน์ • ๋ฌธ์ œ ( "\r\n" ๋Œ€ "\n" )์— ๋Œ€ํ•œ ์˜๊ฒฌ์ด ์žˆ์œผ์‹œ๋ฉด์ด ์Šค๋ ˆ๋“œ์—์„œ ๊ณ„์† ์‘๋‹ต ํ•ด์ฃผ์‹ญ์‹œ์˜ค. ๊ฐ์‚ฌ!

@GrabYourPitchforks ๋ฌธ์„œ์— ์„ค๋ช… ๋œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๊ณ ๋ คํ•˜๋Š” ๋™์•ˆ ๋‹ค์‹œ ์—ฝ๋‹ˆ ๋‹ค.

์—ฌ๊ธฐ์— ๋ช…ํ™•ํ•œ ํ”ผ๋“œ๋ฐฑ์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์œผ๋ฉฐ์ด ๋ฌธ์ œ๋ฅผ ๊ณ„์† ์—…๋ฐ์ดํŠธ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜ ์†Œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์กด์ค‘ํ•˜๊ธฐ์œ„ํ•œ ๋ณ€๊ฒฝ์€ ์˜ํ–ฅ์ด ์ž˜ ๋ฌธ์„œํ™”๋˜์–ด์žˆ๋Š” ํ•œ ๋‚˜๋ฅผ ๊ดด๋กญํžˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ€์ ‘ํ•˜๊ฒŒ ๊ด€๋ จ๋œ ๋ฌธ์ž์—ด ๋ฉ”์„œ๋“œ ํŒจ๋ฐ€๋ฆฌ ๊ตฌ์„ฑ์›์ด ์„œ๋กœ ์ผ๊ด€๋˜์ง€ ์•Š๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ž, ์ž์†Œ ํด๋Ÿฌ์Šคํ„ฐ ๋˜๋Š” ๋กœ์ผ€์ผ์˜ ๋ชจํ˜ธํ•จ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋น„๊ณต์‹์  ์ธ ๋ฌธ์ž์—ด ๋ญ‰ํ‚น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ์€ str.Contains (whatever)๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด str.IndexOf (whatever ) ์šฐ๋ฆฌ๋Š” ๋ฐฉ๊ธˆ ๊ทธ๊ฒƒ์ด ๊ฑฐ๊ธฐ์— ์žˆ๊ณ  ๋”ฐ๋ผ์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ธ์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์„ค์ •์€ ๋ชจ๋“  ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฏธ๋ฌ˜ํ•œ ๋ถ€๋ถ„์„ ์—ฐ๊ตฌ ํ•  ํ•„์š”๊ฐ€ ์—†๋„๋กํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๋ฐฉ๋ฒ•์—์„œ _ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ๋ถˆ์ผ์น˜๋Š” ์ „๋ฌธ๊ฐ€ ๋งŒ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ์–ธ์–ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฝ”๋“œ ์บ ํ”„์—์„œ ๋‚˜์˜ค๋Š” ์‚ฌ๋žŒ๋“ค์„ ์†Œ์™ธ์‹œํ‚ต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์‹์œผ๋กœ ์ง„์ž…ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ์ค€์„ ๋†’์ด ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์˜ˆ, ์ด๊ฒƒ์€ ๋‚ด ๊ฑฑ์ •์„ ์™„์ „ํžˆ ํ‘œํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์ค‘๊ตญ ๊ฐœ๋ฐœ์ž๋กœ์„œ ์šฐ๋ฆฌ๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ์—์„œ ๋ฌธ์ž์—ด ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ StringComparison ๋˜๋Š” CultureInfo ๋ช…์‹œ ์ ์œผ๋กœ ์ž…๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๊ฑฐ์˜ ์—†์œผ๋ฉฐ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” IndexOf ์™€ Contains ์‚ฌ์ด์— ๋‹ค๋ฅธ ํ–‰๋™์„ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!
.net 5.0
image
.net ์ฝ”์–ด 3.1
image
.๋„ท ํ”„๋ ˆ์ž„ ์›Œํฌ
image

@lupestro์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ๋™์ž‘์˜ ๋ถˆ์ผ์น˜๋Š” ๋งค์šฐ ์šฐ๋ ค๋ฉ๋‹ˆ๋‹ค. ์˜ค๋ž˜ ์ง€์†๋˜๋Š” ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฅด๊ฒŒ ํ–‰๋™ํ•˜๊ณ  ์ผ๊ด€๋˜์ง€ ์•Š๊ฒŒ ํ–‰๋™ํ•œ๋‹ค๋ฉด ๋งŽ์€ ์Šฌํ””์ด์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ํ•ญ์ƒ ์ผ๊ด€์„ฑ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. .NET 5.0์—์„œ ๊ฐ‘์ž๊ธฐ ์ผ๊ด€์„ฑ์ด ์—†์–ด์ง€์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ผ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋”ฐ๋ฅด๊ณ  ์žˆ๋‹ค๋ฉด IndexOf ๋Š” ํ•ญ์ƒ ํ˜„์žฌ ๋ฌธํ™” ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ–ˆ๊ณ  Contains ๋Š” ํ•ญ์ƒ ์„œ์ˆ˜ ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ—ˆ๊ฐ€ ๋œ .NET 5.0์€ ๋” ๋งŽ์€ ๋ถˆ์ผ์น˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์„œ ์‹ค์ˆ˜๋Š” ์ด๋Ÿฌํ•œ ๋ถˆ์ผ์น˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ์›๋ž˜ API ์„ค๊ณ„์—์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ผ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋”ฐ๋ฅด๊ณ  ์žˆ๋‹ค๋ฉด IndexOf๋Š” ํ•ญ์ƒ ์„œ์ˆ˜ ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Contains๋Š” ํ•ญ์ƒ ํ˜„์žฌ ๋ฌธํ™” ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ—ˆ๊ฐ€ ๋œ .NET 5.0์€ ๋” ๋งŽ์€ ๋ถˆ์ผ์น˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์„œ ์‹ค์ˆ˜๋Š” ์ด๋Ÿฌํ•œ ๋ถˆ์ผ์น˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ์›๋ž˜ API ์„ค๊ณ„์—์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋งž์Šต๋‹ˆ๋‹ค.ํ•˜์ง€๋งŒ ๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ IndexOf(string) ๋Š” ํ˜„์žฌ ๋ฌธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  IndexOf(char) ๋Š” ์„œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Contains ๋Š” ์„œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ตœ๊ทผ์— ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์–ธ๊ธ‰ ํ•œ IndexOf ๋Œ€ Contains ์ฐจ์ด์— ๋Œ€ํ•ด ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

IndexOf(string) ๋Š” ํ•ญ์ƒ _CurrentCulture_ ๋น„๊ต๋ฅผ ๊ฐ€์ •ํ–ˆ์œผ๋ฉฐ Contains(string) ๋Š” ํ•ญ์ƒ _Ordinal_ ๋น„๊ต๋ฅผ ๊ฐ€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ถˆ์ผ์น˜๋Š” .NET Framework์—์„œ ๋‹ค์‹œ ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” .NET 5์— ๋„์ž… ๋œ ์ƒˆ๋กœ์šด ๋ถˆ์ผ์น˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด .NET Framework (Windows์˜ NLS ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ)์—์„œ ํ•ฉ์ž "รฆ"์™€ ๋‘ ๋ฌธ์ž ๋ฌธ์ž์—ด "ae"๋Š” ์–ธ์–ด ๋น„๊ต ์ž์—์„œ ๋™์ผํ•œ ๊ฒƒ์œผ๋กœ ๋น„๊ต๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

// Sample on .NET Framework, showing Contains & IndexOf returning inconsistent results
Console.WriteLine("encyclopรฆdia".Contains("ae")); // prints 'False'
Console.WriteLine("encyclopรฆdie".IndexOf("ae")); // prints '8' (my machine is set to en-US)

์ด๋Ÿฌํ•œ ๋ถˆ์ผ์น˜๋Š” 10 ๋…„ ์ด์ƒ ์กด์žฌ ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œํ™” ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ด์— ๋Œ€ํ•œ https://github.com/dotnet/runtime/issues/43956 ์—์„œ ์ƒํƒœ๊ณ„๋ฅผ ๋”์šฑ ๊ฑด์ „ํ•˜๊ฒŒ ๋ฐœ์ „์‹œํ‚ฌ ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŠน์ • ๋ฌธ์ œ์— ๋Œ€ํ•ด ์šฐ๋ฆฌ๊ฐ€ ์ง„์ •์œผ๋กœ ์ž๋ฌธํ•˜๊ณ ์žˆ๋Š” ๊ฒƒ์€ "๋ถˆ์ผ์น˜๊ฐ€ ์˜์›ํžˆ ์กด์žฌํ–ˆ์Œ์„ ๊ฐ์•ˆํ•  ๋•Œ,์ด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ๋” ํฐ ์ƒํƒœ๊ณ„์— ํ•ด๋ฅผ ๋ผ์น˜๊ธฐ ์ „์— _ ์‹ค์ œ๋กœ _ ์ดํƒˆ ํ•  ์ˆ˜์žˆ๋Š” ๊ฑฐ๋ฆฌ๋Š” ์–ผ๋งˆ์ž…๋‹ˆ๊นŒ?"์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์—ฌ์ „ํžˆ ๊ทธ ์ž„๊ณ„ ๊ฐ’์ด ์žˆ์–ด์•ผ ํ•  ๊ณณ์„ ์ •์˜ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ณด๊ณ ์„œ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์‹ค์ œ๋กœ ์ด๋Ÿฌํ•œ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๊ณ ๊ฐ์˜ ํ–‰๋™์— ๋Œ€ํ•ด ๊ธฐ๋Œ€ํ•˜๋Š” ๋ฐ”์— ๋Œ€ํ•œ ํ†ต์ฐฐ๋ ฅ์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— _ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค _. ํ”„๋ ˆ์ž„ ์›Œํฌ์˜ ๊ด€๋ฆฌ์ž๋กœ์„œ ์šฐ๋ฆฌ๋Š” ๊ธฐ์ˆ  ๋ฌธ์„œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‹ค์ œ ์•ฑ์ด ์ด๋Ÿฌํ•œ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๋„ ๊ณ ๋ คํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด ์˜๊ฒฌ์€ ํŠน์ • ๊ด€์ ์„ ๋ฐฉ์–ดํ•˜๊ธฐ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ œ ์˜๋„๋Š” ์ œ๊ฐ€ ๋ณธ ๋ช‡ ๊ฐ€์ง€ ์˜คํ•ด๋ฅผ ๋ช…ํ™•ํžˆํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ–ˆ๋Š”์ง€ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

InvariantCulture๊ฐ€ ์ง€์ •๋˜์–ด ์žˆ์–ด๋„ ICU ๋ฒ„์ „์—์„œ \n ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ๋™์ž‘์ž…๋‹ˆ๊นŒ?

image
image

์•„๋งˆ๋„ ๋‹ค์Œ ์ฝ”๋“œ๋Š” git ๋ฐ ๊ธฐ๋ณธ ์„ค์ • (autocrlf = true)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Linux์—์„œ 5, Windows์—์„œ -1์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๊นŒ?

using System;

var s = @"hello
world";
Console.WriteLine(s.IndexOf("\n", StringComparison.InvariantCulture));

@ufcpp ์˜ˆ,์ด ์Šค๋ ˆ๋“œ์˜ ์•ž๋ถ€๋ถ„์—์„œ ์„ค๋ช…ํ•œ๋Œ€๋กœ ์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘ ์ธ ICU ๋‹น. 2 ๊ฐœ์˜ ๋ฌธ์ž <CR><LF> ๋Š” ์„œ๋กœ ์ธ์ ‘ ํ•ด์žˆ์„ ๋•Œ ์–ธ์–ด ๋ชฉ์  ์ƒ ๊นจ์ง€์ง€ ์•Š๋Š” ๋‹จ์œ„๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์–ธ์–ด ๋น„๊ต ์ž (์˜ˆ : _InvariantCulture_)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ <LF> ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด์ด ๊นจ์ง€์ง€ ์•Š๋Š” ๋‹จ์œ„๋ฅผ ๋ถ„ํ• ํ•˜๋ฏ€๋กœ ์ผ์น˜ํ•˜๋Š” ํ•ญ๋ชฉ์ด ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์‚ฌ๋žŒ๊ณผ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ICU๋ฅผ 5.0 GA์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์œ ์ง€ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/dotnet/runtime/issues/43956 ์—์„œ ์ถ”์ ๋˜๋Š” ์„œ์ˆ˜๋ฅผ ์˜๋„ํ–ˆ์„ ๋•Œ ์‹ค์ˆ˜๋กœ ์–ธ์–ด ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ •์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค

์ด๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ค์šด ๊ฒฐ์ •์ด์—ˆ๊ณ , ํ”Œ๋žซํผ ๊ฐ„ ํ‘œ์ค€ํ™”๋ฅผ์œ„ํ•œ ๋“œ๋ผ์ด๋ธŒ์™€ ์ƒํƒœ๊ณ„์— ๋ฏธ์น˜๋Š” ํ˜ธํ™˜์„ฑ ์˜ํ–ฅ์„ ๋น„๊ตํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์™„ํ™” ์กฐ์น˜๊ฐ€ ๋ถˆ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋Š” ๊ฒฝ์šฐ ์„œ๋น„์Šค์‹œ \r\n ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์™„ํ™”๋ฅผ ๊ณ ๋ คํ•˜๊ธฐ ์œ„ํ•ด์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ์‚ฌ๋žŒ๋“ค์ด ICU ์Šค์œ„์น˜์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๊ณ„์†๋ณด๊ณ ํ•˜๋„๋ก ์žฅ๋ คํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋น„๋ก ๊ทธ ๋™์ž‘์ด ์•Œ๋ ค์ง„ ์›์ธ ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๊ฒƒ์ด "์„ค๊ณ„์— ์˜ํ•œ"๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ณ„์†ํ•ด์„œ ์ฐจ์ด์ ์„ ์กฐ์‚ฌํ•˜๊ณ  ๊ทผ๋ณธ ์›์ธ์„ ์ดํ•ดํ•˜๊ณ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ICU ๋˜๋Š” .NET์œผ๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•ด์•ผํ•˜๋Š”์ง€ ๊ฒฐ์ •ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•ญ์ƒ StringComparison์„ ์ง€์ •ํ•˜๋Š” ๋ถ„์„๊ธฐ ๊ทœ์น™์ด ์žˆ์Šต๋‹ˆ๋‹ค.

https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1307

๋ชจ๋“  ์‚ฌ๋žŒ๊ณผ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ICU๋ฅผ 5.0 GA์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์œ ์ง€ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์„œ์ˆ˜๋ฅผ ์˜๋„ํ–ˆ์„ ๋•Œ ์šฐ์—ฐํžˆ ์–ธ์–ด ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ •์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋Š” # 43956์—์„œ ์ถ”์ ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ์ด ๋ฌธ์ œ์˜ ์˜ํ–ฅ์„๋ฐ›์€ ๊ฒƒ์œผ๋กœ ํ™•์ธ ๋œ ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์—ฐ๋ฝ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋‹ค๊ฐ€์˜ค๋Š” 5.0 ๋ฆด๋ฆฌ์Šค์™€ ํ•จ๊ป˜ ์‚ฌ๋žŒ๋“ค์ด ๋ฌธ์ œ๊ฐ€์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋” ์ž˜ ์‹๋ณ„ํ•˜๊ณ ์ด ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๋” ๋งŽ์€ ๋ฌธ์„œ๋ฅผ ๊ณต์œ  ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ค์šด ๊ฒฐ์ •์ด์—ˆ๊ณ , ํ”Œ๋žซํผ ๊ฐ„ ํ‘œ์ค€ํ™”๋ฅผ์œ„ํ•œ ๋“œ๋ผ์ด๋ธŒ์™€ ์ƒํƒœ๊ณ„์— ๋ฏธ์น˜๋Š” ํ˜ธํ™˜์„ฑ ์˜ํ–ฅ์„ ๋น„๊ตํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์™„ํ™” ์กฐ์น˜๊ฐ€ ๋ถˆ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋Š” ๊ฒฝ์šฐ ์„œ๋น„์Šค์‹œ \r\n ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์™„ํ™”๋ฅผ ๊ณ ๋ คํ•˜๊ธฐ ์œ„ํ•ด์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ์‚ฌ๋žŒ๋“ค์ด ICU ์Šค์œ„์น˜์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๊ณ„์†๋ณด๊ณ ํ•˜๋„๋ก ์žฅ๋ คํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋น„๋ก ๊ทธ ๋™์ž‘์ด ์•Œ๋ ค์ง„ ์›์ธ ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๊ฒƒ์ด "์„ค๊ณ„์— ์˜ํ•œ"๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ณ„์†ํ•ด์„œ ์ฐจ์ด์ ์„ ์กฐ์‚ฌํ•˜๊ณ  ๊ทผ๋ณธ ์›์ธ์„ ์ดํ•ดํ•˜๊ณ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ICU ๋˜๋Š” .NET์œผ๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•ด์•ผํ•˜๋Š”์ง€ ๊ฒฐ์ •ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ œ์–ด ํ•  ์ˆ˜์—†๋Š” .NET Standard ์ข…์†์„ฑ์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ•  ์ˆ˜ ์—†์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด .NET Standard 2.2๋กœ ์ „ํ™˜ํ•˜๋„๋กํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? API๋ฅผ ๋ณ€๊ฒฝ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘์„ ์–ป๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฏธ ๊ณต์ •ํ•œ ๋ชซ์„ ์ฐจ์ง€ํ•˜๊ณ ์žˆ๋Š” ํ˜„์žฌ ์ƒํƒœ๊ณ„์˜ ํŒŒ๊ดด๋ฅผ ์–ด๋–ป๊ฒŒ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ‹€๋ ธ๋‹ค๋Š” ๊ฒƒ์ด ์ฆ๋ช…๋˜์–ด ๊ธฐ์  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŽธ๊ฒฌ์„ ๊ฐ€์ง€๊ณ  ๊ทธ๋ ‡๊ฒŒ ํ•ด์ฃผ์„ธ์š”-๊ทธ๊ฒƒ์€ ๋‚ด ๋งˆ์Œ์„ ํŽธ์•ˆํ•˜๊ฒŒ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

๋ฟก๋ฟก

๋‚ด๊ฐ€ ์ œ์–ด ํ•  ์ˆ˜์—†๋Š” .NET Standard ์ข…์†์„ฑ์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

.Net Standard ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํฌ๋กœ์Šค ํ”Œ๋žซํผ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ˜„์žฌ Unix์˜ .Net Core 3 (ICU ์‚ฌ์šฉ)์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๋ฉด Windows (ICU๋„ ์‚ฌ์šฉํ•˜๋Š”)์˜ .Net 5์—์„œ๋„ ๊ฑฐ์˜ ํ™•์‹คํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

.NET ํ‘œ์ค€ 2.2

.Net Standard vNext๋Š” ".Net 5.0"์ด๋ผ๊ณ ํ•˜์ง€๋งŒ ํšจ๊ณผ์ ์œผ๋กœ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. (์ฆ‰, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑ ์ค‘์ด๊ณ  ์ด์ „ ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ์˜ค๋Š˜์€ .Net Standard 2.1์„ ๋Œ€์ƒ์œผ๋กœํ•ฉ๋‹ˆ๋‹ค. ํ•œ ๋‹ฌ ์•ˆ์— .Net 5.0์„ ๋Œ€์ƒ์œผ๋กœํ•ฉ๋‹ˆ๋‹ค.)

@svick ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค . .NET Standard์˜ ์ž‘๋™ ๋ฐฉ์‹์„ ์ด๋ฏธ ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” .NET 5๊ฐ€ ์ƒˆ๋กœ์šด .NET ํ‘œ์ค€์ด๋ผ๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

์ฃ„์†กํ•˜์ง€๋งŒ IndexOf์™€ Contains ์‚ฌ์ด์˜ ๊ธฐ์กด ๋™์ž‘ ๋ถˆ์ผ์น˜์— ์˜์กดํ•˜๋Š” .NET Standard 2.1 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์–ด๋–ป๊ฒŒ๋˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ณ€ํ™”ํ•˜๋Š” ๊ฒƒ์€ ๋Œ€์—ญ ์™ธ, ICU ๋Œ€ NLS์ž…๋‹ˆ๋‹ค. ์ด ๋ณ€ํ™”๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด๋ฏธ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ๋ถˆ์ผ์น˜๋ฅผ ๋„“ํžˆ๊ณ  ๊ธฐ๋Œ€์น˜๋ฅผ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค.
์ด ์ •๋ณด๋ฅผ libs๋กœ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์ƒˆ๋กœ์šด ๋…ธ๋ฉ€์— ๋Œ€ํ•œ ์›ํ™œํ•œ ์˜จ ๋ณด๋”ฉ ๊ฒฝ๋กœ ์—†์ด๋Š” "๊ธฐ์ˆ ์ ์œผ๋กœ ์ •ํ™•"ํ•˜๋‹ค๋Š” ๋Š๋‚Œ์„ ๋–จ์ณ ๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ ˆ์‹คํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด, ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ ์ตœ๊ณ ์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ตฌ์„ฑ์›์ด ๋ฌด์ž‘์œ„๋กœ ๋ฐœ๊ฒฌ ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ์ง€์ง„ ๋ณ€ํ™”๋Š” ๋งํ•  ๊ฒƒ๋„์—†๊ณ  ์ƒˆ๋กœ์šด ์–ธ์–ด ๊ธฐ๋Šฅ๋„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์„ ๊ฒฌ๋”œ ์ˆ˜์žˆ๋Š” ๊ธฐํšŒ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ์ œ์–ด ํ•  ์ˆ˜์—†๋Š” .NET Standard ์ข…์†์„ฑ์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ณ€ํ™”ํ•˜๋Š” ๊ฒƒ์€ ๋Œ€์—ญ ์™ธ, ICU ๋Œ€ NLS์ž…๋‹ˆ๋‹ค. ์ด ๋ณ€ํ™”๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด๋ฏธ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ๋ถˆ์ผ์น˜๋ฅผ ๋„“ํžˆ๊ณ  ๊ธฐ๋Œ€์น˜๋ฅผ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ICU๊ฐ€ ์œ ๋‹‰์Šค์—์„œ _ ํ•ญ์ƒ _ ์‚ฌ์šฉ๋˜์–ด ์™”๋‹ค๋Š” ๊ฒƒ์€ ์—ฌ๊ธฐ์„œ ์ถฉ๋ถ„ํžˆ ๊ฐ•์กฐ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. .NET Standard ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์„ค๊ณ„ ์ƒ ์ด์‹ ๊ฐ€๋Šฅํ•ด์•ผํ•˜๋ฉฐ ์ด์ „์— Linux .NET Core 3.x์—์„œ ์ž‘๋™ํ–ˆ๋˜ ๋ชจ๋“  ๊ฒƒ์ด .NET 5์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์€ InvariantCulture์ž…๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ด์ „์— ์ดํ•ด ํ•œ ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์„ค๊ณ„ ์ƒ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์‹ค์ด ์•„๋‹ˆ๋‹ค. InvariantCulture๋Š” ์‚ฌ์šฉ์ž์˜ ์–ธ์–ด ์„ค์ • ๋งŒ ๋ฌด์‹œํ•˜๋„๋ก๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ๋‹ˆ ์ฝ”๋“œ ์‚ฌ์–‘์ด๋‚˜ ์„ธ๊ณ„ํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋กœ ์—ฌ์ „ํžˆ ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

.NET ํŒ€์€ ์ด๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜์žˆ๋Š” ๊ณ ํ†ต๊ณผ ๋ฌธ์ œ์  ๋ฐ ๋น„์šฉ์„ ๊ณ ๋ ค ํ–ˆ์Šต๋‹ˆ๊นŒ?

์ด์™€ ๊ฐ™์€ ๋ฐœ์–ธ์€ ๋์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ์œผ๋กœ ๊ฐ‘์ž๊ธฐ ์ค‘๋‹จ๋˜๋Š” ์ฝ”๋“œ๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค. .NET ํŒ€์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š๊ฑฐ๋‚˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์— ์˜์กดํ•˜๋Š” ์‚ฌ์šฉ์ž ์ฝ”๋“œ์˜ ๋™์ž‘์„ ์œ ์ง€ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ํ”Œ๋žซํผ์€ ์–ด๋–ป๊ฒŒ ๋ฐœ์ „ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ํ˜ธํ™˜์„ฑ ์Šค์œ„์น˜๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์€ ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. .NET Core๊ฐ€ .NET Framework์—์„œ ๋ถ„๋ฆฌ ๋œ ์ด์œ ์˜ ํฐ ๋ถ€๋ถ„์€ side-by-side ์„ค์น˜ ๋ฐ ์•ฑ-๋กœ์ปฌ ๋Ÿฐํƒ€์ž„ ๋ฐฐํฌ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ์˜€์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— .NET 5๋กœ ์ด๋™ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด .NET 5๋กœ ์ด๋™ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

.NET 5๊ฐ€ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์ƒˆ๋กœ์šด ์ž‘๋ฌผ์„ ๋„์ž…ํ•˜๊ณ  ๋‚ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์šด ์ŠคํŠธ๋ฆผ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์„ ๋‹ค์‹œ ๊ฒ€ํ†  ํ•  ๊ฒƒ์ด๋ผ๋Š” ์ „๋ง์— ํฅ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฃผ์žฅํ•˜๋Š”๋Œ€๋กœ ํ”Œ๋žซํผ ์ฐจ์ด ๋ฒ„๊ทธ๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ–ˆ๋‹ค๋ฉด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

.NET ํŒ€์€ ์ด๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜์žˆ๋Š” ๊ณ ํ†ต๊ณผ ๋ฌธ์ œ์  ๋ฐ ๋น„์šฉ์„ ๊ณ ๋ ค ํ–ˆ์Šต๋‹ˆ๊นŒ?

์ด์™€ ๊ฐ™์€ ๋ฐœ์–ธ์€ ๋์ด ์—†์Šต๋‹ˆ๋‹ค.

์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ .NET์—์„œ ์‹คํ–‰๋˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ฌธ์ž์—ด ์กฐ์ž‘์€ ๋งค์šฐ ๋นˆ๋ฒˆํ•œ ์ž‘์—…์ž…๋‹ˆ๋‹ค.
.NET ํŒ€์ด์ด ๋ฌธ์ œ๋ฅผ ์ˆ˜์ • / ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐ ๋“œ๋Š” ๋…ธ๋ ฅ์€ .NET 5/6์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋  ๋ชจ๋“  ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋…ธ๋ ฅ์— ๋น„ํ•ด ์•„์ฃผ ์ ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ์œ„ํ•œ "๊ณ„ํš"์— ๋Œ€ํ•ด ๋ฌผ์–ด ๋ณด๋Š” ๊ฒƒ์€ ์ƒ๋‹นํžˆ ๊ณต์ •ํ•ฉ๋‹ˆ๋‹ค.
๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?
์ด ๋ณ€๊ฒฝ์˜ ํšจ๊ณผ๊ฐ€ ์˜ˆ์ƒ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?
๋ชจ๋“  ํ”„๋กœ์ ํŠธ์˜ 0.001 %์ž…๋‹ˆ๊นŒ? 75 %์ž…๋‹ˆ๊นŒ?
์šฐ๋ฆฌ๊ฐ€ ์•Œ์ง€ ๋ชปํ•˜๋Š” ๋‹ค๋ฅธ ์œ ์‚ฌํ•œ ๋ณ€ํ™”๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ์†Œ์ˆ˜์˜ ํ”„๋กœ์ ํŠธ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ถ”์ • ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

BTW, ๋‚˜๋Š” ์ถฉ๋ถ„ํ•œ ์ด์œ ๋ฅผ ๊ณ ๋ คํ•  ๋•Œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊นจ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋„ˆ๋ฌด ์œ„ํ—˜ํ•˜์ง€ ์•Š์€ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฒฝ๋กœ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@petarrepac ์˜คํ•ด ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋‚˜์ด ์Šค๋ ˆ๋“œ์—์„œ ์—ฌ๋Ÿฌ ๋ฒˆ ์ง€์ ํ–ˆ๋“ฏ์ด :

  1. ๊ณ„ํš์ด ์žˆ์œผ๋ฉฐ ๋Ÿฐํƒ€์ž„ ๊ตฌ์„ฑ ์Šค์œ„์น˜๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  2. ์ค‘๋‹จ๋˜์—ˆ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๋Š” ๋™์ž‘์€ ๋ชจ๋“  ๋น„ Windows ํ”Œ๋žซํผ์—์„œ .NET์˜ ๊ธฐ์กด ๋™์ž‘์ž…๋‹ˆ๋‹ค.
  3. ์ด๋Š” ์„œ ์ˆ˜๊ฐ€ ์˜๋„ ๋œ ๋ฌธํ™”๊ถŒ์— ๋ฏผ๊ฐํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰ ๋‘ ๊ฐ€์ง€ ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ์ด๊ฒƒ์ด ์ƒ๋‹นํžˆ ์ ์€ ๋น„์œจ์˜ ํ”„๋กœ์ ํŠธ์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์  ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

100 % ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋ฌผ์–ด ๋ณด๋Š” ๊ฒƒ์€ ๊ณตํ‰ํ•˜์ง€๋งŒ, ์ œ๊ฐ€ ์ธ์šฉ ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ข…์ข… ๋ณ€ํ™”์˜ ๋” ํฐ ๊ทธ๋ฆผ์„ ์ดํ•ดํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ธฐ ์ „์— ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ์ž‘์„ฑํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋‘๋“ค ์•ˆ๋…•. ์ด ๋ฌธ์ œ๊ฐ€ ๊ณต๊ฐœ๋˜์—ˆ์„ ๋•Œ ์ทจํ•œ ์กฐ์น˜์™€ ๋งˆ์ง€๋ง‰์— Windows 10 2019 ๋…„ 5 ์›” ์—…๋ฐ์ดํŠธ ์ด์ƒ์—์„œ ๊ธฐ๋ณธ๊ฐ’์„ .NET 5.0 ์šฉ ICU๋กœ ์œ ์ง€ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ์ด์œ ์— ๋Œ€ํ•œ ๊ฐ„๋žตํ•œ ์š”์•ฝ์„ ์ œ๊ณตํ•˜๊ณ ์žํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์„ ๋•Œ ์šฐ๋ฆฌ๋Š” Ordinal ์™€ IndexOf(string) ์‚ฌ์ด์˜ ๋ถˆ์ผ์น˜๋ฅผ ๊ฐ์•ˆํ•  ๋•Œ ๊ณ ๊ฐ์—๊ฒŒ ๋ฏธ์น  ์ˆ˜์žˆ๋Š” ์ž ์žฌ์  ์ธ ์˜ํ–ฅ๊ณผ ๊ณ ํ†ต์— ๋Œ€ํ•œ ๋‚ด๋ถ€ ํ† ๋ก ์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค Contains(string) IndexOf(string) ๋ฌธํ™” ์ธ์‹ํ•˜๊ณ , ํ”Œ๋Ÿฌ์Šค ๋ฌธ์ž์—ด์„ ํ†ตํ•ด ์ž‘๋™ ํ•  ๋•Œ ๋‹ค๋ฅธ API๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌธํ™” ์ธ์‹ํ•˜๊ณ  ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ์ธ Ordinal ํ†ตํ•ด ์ž‘๋™ ํ•  ๋•Œ Span<char> ๋˜๋Š” ReadOnlySpan<char> . ๋”ฐ๋ผ์„œ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•œ ํ›„ ์˜ํ–ฅ์„๋ฐ›์„ ์ˆ˜์žˆ๋Š” NuGet ํŒจํ‚ค์ง€์— ๋Œ€ํ•œ ๋ถ„์„์„ ์‹œ์ž‘ํ•˜๊ณ  ๋ช…ํ™•ํ•œ ๊ทธ๋ฆผ์„ ์–ป๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์šฐ๋ฆฌ์˜ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

  • "\ n"์€ IndexOf, LastIndexOf, EndsWith, StartsWith, Compare ๋ฐ CompareTo์— ์ „๋‹ฌ ๋œ "๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด"์—์„œ # 30์ž…๋‹ˆ๋‹ค.
  • String.EndsWith์— ๋Œ€ํ•œ ํ˜ธ์ถœ ์‚ฌ์ดํŠธ์˜ 1 %๋Š” \ n์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒ€์ƒ‰ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ์ค‘์ธ ๋ฌธ์ž์—ด์— "์œˆ๋„์šฐ ์Šคํƒ€์ผ ๋ผ์ธ ์—”๋”ฉ"์ด ํฌํ•จ ๋œ ์ฝœ ์‚ฌ์ดํŠธ๋Š” ๋ชจ๋‘ ์†์ƒ๋ฉ๋‹ˆ๋‹ค.
  • ๋ฒ„์ „์— ์œ„ํ—˜ ํ˜ธ์ถœ ์‚ฌ์ดํŠธ๊ฐ€์žˆ๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ๊ฐ€ ํฌํ•จ ๋œ NuGet.org์—์„œ ํ˜ธ์ŠคํŒ…๋˜๋Š” 2040 ํŒจํ‚ค์ง€ ID๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ์ฝœ ์‚ฌ์ดํŠธ์˜ ๋Œ€๋ถ€๋ถ„์€ EndsWith ๋ฐ IndexOf์— ๋Œ€ํ•œ ๊ฒƒ์ด๋ฉฐ, ์ด๋Š”์ด ํŒจํ„ด์ด ์ˆœ์ง„ํ•œ ์ค„ ๋ฐ”๊ฟˆ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์ž์ฃผ ์‚ฌ์šฉ๋œ๋‹ค๋Š” ๊ฐ€์„ค๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์œ„ํ—˜์— ์ฒ˜ํ•œ ํ˜ธ์ถœ ์‚ฌ์ดํŠธ๊ฐ€์žˆ๋Š” ์ด๋Ÿฌํ•œ 2040 ํŒจํ‚ค์ง€ ์ค‘ 539 ๊ฐœ๋งŒ .NET Standard ๋˜๋Š” .NET Core์˜ ์ผ๋ถ€ ๋ฒ„์ „์„ ์ง€์›ํ•˜๋ฏ€๋กœ NuGet.org์— ๋‚˜์—ด๋œ 0.54 % ํŒจํ‚ค์ง€ ๋งŒ ์ค‘๋‹จ์— ๋…ธ์ถœ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ž ์žฌ์ ์œผ๋กœ ์˜ํ–ฅ์„๋ฐ›์„ ์ˆ˜์žˆ๋Š” 539 ๊ฐœ์˜ ํŒจํ‚ค์ง€ ID ๋ชฉ๋ก์—์„œ ํŒจํ‚ค์ง€๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‹ค์ œ ์˜ํ–ฅ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ƒ์œ„ 70 ๊ฐœ (๋‹ค์šด๋กœ๋“œ ์ˆ˜ ๊ธฐ์ค€)๋ฅผ ์‚ดํŽด ๋ณด์•˜๊ณ , 20 ๊ฐœ๋Š” ์ตœ์‹  ๋ฒ„์ „์—์„œ ํŒจํ„ด์„ ๋…ธ์ถœํ•˜์ง€ ์•Š์•˜์œผ๋ฉฐ, ํŒจํ„ด์„ ๋…ธ์ถœ ํ•œ ํŒจํ„ด์€ ํ—ˆ์šฉ ๋ผ์ด์„ ์Šค๊ฐ€์žˆ๋Š” 32 ๊ฐœ๋งŒ ๋ณผ ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • 14๋Š” ๋ฒ„๊ทธ์˜ ๋Œ€์ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • 13 ๊ฐœ๊ฐ€ ์ž ์žฌ์ ์œผ๋กœ ์†์ƒ๋จ
  • 5 ๊ฐœ๋Š” ๋ถˆํ™•์‹คํ–ˆ์Šต๋‹ˆ๋‹ค (๋‹ค์–‘ํ•œ ์ค„ ๋ฐ”๊ฟˆ ํŒจํ„ด์ด๋‚˜ ๊ธฐํƒ€ ์™„ํ™”์— ๋Œ€ํ•œ ๋ฐฉ์–ด ์  ์ฝ”๋”ฉ์œผ๋กœ ์ธํ•ด ๋Š๊น€์ด ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œ์‹œ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค).

์ฆ‰, ๋‹ค์šด๋กœ๋“œ ๊ธฐ์ค€ ์ƒ์œ„ 70 ๊ฐœ ํŒจํ‚ค์ง€ ์ค‘ 18 %๋งŒ์ด ์ž ์žฌ์ ์œผ๋กœ ์˜ํ–ฅ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฑ๋ถ„์œจ์€ ๋ˆ„์ ๋˜๋ฉฐ NuGet.org์˜ ์ด ํŒจํ‚ค์ง€ ์ˆ˜์ธ 229,536 ๊ฐœ์™€ ๋น„๊ต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ NuGet.org์—์„œ ์ด ํŒจํ‚ค์ง€ ์ˆ˜์™€ ์ด ๋‹ค์šด๋กœ๋“œ ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด 0.24 % ์ธ 229,536 ๊ฐœ ์ค‘ ์ž ์žฌ์ ์œผ๋กœ ์˜ํ–ฅ์„๋ฐ›๋Š” 539 ๊ฐœ์˜ ํŒจํ‚ค์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์€ ์ข‹์ง€๋งŒ nuget์€ C # ์ฝ”๋“œ์˜ ๊ทนํžˆ ์ผ๋ถ€์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ฝ”๋“œ๋ฅผ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋”๋ผ๋„ a) ๋ฒ„๊ทธ๋ฅผ ์ถ”์ ํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ b) ๋” ์ด์ƒ ์†Œ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋™์ž‘์—์žˆ์–ด ๋งค์šฐ ์ฃผ๋ชฉํ• ๋งŒํ•œ ๋ณ€ํ™” ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ Windows Line Endings (ํ”ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Œ)๋ฅผ ํฌํ•จ ํ•  ์ˆ˜์žˆ๋Š” ์ž…๋ ฅ์„ ์ฝ์„ ๋•Œ ์ด๋ฏธ Unix์—์„œ ๋ฐœ์ƒํ•œ ์ค‘๋‹จ์ด๋ผ๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆด ์ˆ˜์žˆ๋Š” ์ข‹์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์˜€์Šต๋‹ˆ๋‹ค.

.NET Core ๋ฐ .NET 5+์—์„œ ์šฐ๋ฆฌ๋Š” OS ๊ฐ„์˜ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์œผ๋ฉฐ์ด ๋ณ€๊ฒฝ์˜ ์˜ํ–ฅ์„ ๊ณ ๋ คํ•  ๋•Œ ์˜ฌ๋ฐ”๋ฅธ ์ž‘์—…์ฒ˜๋Ÿผ ๋Š๊ปด์กŒ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ˜ธํ™˜์„ฑ์— ๊ด€์‹ฌ์ด ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ๋žŒ๋“ค์ด ๋ ˆ๊ฑฐ์‹œ ๋™์ž‘์œผ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ํ˜ธํ™˜๋˜๋Š” ๋Ÿฐํƒ€์ž„ ์Šค์œ„์น˜๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์šฐ๋ฆฌ๊ฐ€ ๊ฒ€์‚ฌ ํ•  ์ˆ˜์žˆ๋Š” ํŒจํ‚ค์ง€์˜ ๊ฒฐ๋ก ์€ ์ด๋ฏธ Unix์—์„œ ๋™์ž‘์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋ฐฉ์–ด์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋งŽ์ด ํ™•์ธํ•˜์—ฌ OS ๊ฐ„ ์ž ์žฌ์  ์ธ ์ค‘๋‹จ์„ ์™„ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋ง๋ถ™์—ฌ์„œ, ์„ธ๊ณ„ํ™”๋Š” ์šฐ๋ฆฌ๊ฐ€ OS ์ „๋ฐ˜์— ๊ฑธ์ณ ์–‡์€ ๋ž˜ํผ์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ธ์ œ๋“ ์ง€ ๋ณ€๊ฒฝ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ˜„์žฌ ์šฐ๋ฆฌ๊ฐ€ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  OS์—์„œ ๋™์ผํ•œ ๋ž˜ํผ๊ฐ€๋˜๋Š” ๊ฒƒ์ด ์˜ณ์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๊ปด์กŒ์Šต๋‹ˆ๋‹ค.

๊ทธ ์ผํ™˜์œผ๋กœ ์‹ค์ œ ์˜ˆ์ œ, roslyn ๋ถ„์„๊ธฐ ๊ทœ์น™ ๋ฐ ์˜ํ–ฅ์„๋ฐ›๋Š” ์ฝ”๋“œ๊ฐ€์ด๋ฅผ ์™„ํ™” ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฌธ์„œ๋ฅผ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ญ์ƒ ์šฐ๋ฆฌ๋ฅผ ๋” ๋‚˜์€ ๊ณณ์œผ๋กœ ๋ฐ๋ ค๊ฐ€๋Š” ๊ท€์ค‘ํ•œ ํ”ผ๋“œ๋ฐฑ์— ๊ฐ์‚ฌ ๋“œ๋ฆฌ๋ฉฐ, https://github.com/dotnet/runtime/issues/43956์—์„œ ๋…ผ์˜ ๋œ๋Œ€๋กœ .NET 6์— ๋Œ€ํ•œ์ด ๊ฒฝํ—˜์„ ๊ณ„์† ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Unix์™€ Windows์—์„œ ์ค„ ๋์˜ ์ฐจ์ด๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜์žˆ๋Š” ๊ณ ํ†ต์„ ์ดํ•ดํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ์ด ๋ฌธ์ œ๋ฅผ ๊ณ„์† ๊ณต๊ฐœํ•˜๊ณ  .NET 5.0์˜ \r\n ์‚ฌ๋ก€๋ฅผ ์™„ํ™” ํ•  ์ˆ˜์žˆ๋Š” ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์„ ์กฐ์‚ฌ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. .x๋Š” ์„œ๋น„์Šค ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€ ์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค.

char ๋ฐ string์—๋„ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Console.WriteLine("com/test/test/test/a/b/สน$สน".IndexOf("$"));
Console.WriteLine("com/test/test/test/a/b/สน$สน".IndexOf('$'));
24

@mattleibow ๋ฌธ์ž ๊ฒ€์ƒ‰์„ ์‚ฌ์šฉํ•˜๋ฉด ์„œ์ˆ˜ ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. This method performs an ordinal (culture-insensitive) search ๋‚˜ํƒ€๋‚ด๋Š” https://docs.microsoft.com/en-us/dotnet/api/system.string.indexof?view=net-5.0#System_String_IndexOf_System_Char_ ๋ฌธ์„œ. ์„œ์ˆ˜ ์˜ต์…˜์œผ๋กœ ๋ฌธ์ž์—ด ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ฌธ์ž์™€ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

C# Console.WriteLine("com/test/test/test/a/b/สน$สน".IndexOf("$", StringComparison.Ordinal));

~์ด ๋ณด์ธ๋‹ค CA1307์€ ๋‹จ์ง€ ํŠธ๋ฆฌ๊ฑฐ indexof(char) ์žˆ์ง€๋งŒ indexof(string) . string ๋ฒ„์ „์— ๋Œ€ํ•œ ๊ทœ์น™์ด ์žˆ์Šต๋‹ˆ๊นŒ? char ์˜ ๊ธฐ๋ณธ๊ฐ’์ด ์ž๋™์œผ๋กœ ์„œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์‹ค์ œ๋กœ ์ด์— ์˜ํ–ฅ์„์ฃผ์ง€ ์•Š๋Š” ๋ฐ˜๋ฉด string ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฉฐ ๋™์ž‘์„ ๋ณต์›ํ•˜๋ ค๋ฉด ์„œ์ˆ˜๋ฅผ ์ง€์ •ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋” ์ค‘์š”ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋ช‡๋ช‡ ๊ฒฝ์šฐ. ~

~ indexof(string) ๋Š” ์–ด๋–ป๊ฒŒ ๊ฐ์ง€ํ•ฉ๋‹ˆ๊นŒ? ~

์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๊ทœ์น™ CA1310์ž…๋‹ˆ๋‹ค. https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu#use -nls-instead-of-icu์— ๋Œ€ํ•œ ๋ฌธ์„œ๋Š” ์ž˜๋ชป๋˜์—ˆ์œผ๋ฉฐ์ด ํŠน์ • ๋ณ€ํ˜•์„ ์–ธ๊ธ‰ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ํ•ด๋‹น ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰