icu.net 3.0.3-beta.34

This is a prerelease version of icu.net.
There is a newer version of this package available.
See the version list below for details.
dotnet add package icu.net --version 3.0.3-beta.34
                    
NuGet\Install-Package icu.net -Version 3.0.3-beta.34
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="icu.net" Version="3.0.3-beta.34" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="icu.net" Version="3.0.3-beta.34" />
                    
Directory.Packages.props
<PackageReference Include="icu.net" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add icu.net --version 3.0.3-beta.34
                    
#r "nuget: icu.net, 3.0.3-beta.34"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package icu.net@3.0.3-beta.34
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=icu.net&version=3.0.3-beta.34&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=icu.net&version=3.0.3-beta.34&prerelease
                    
Install as a Cake Tool

icu.net

Overview

icu-dotnet is the C# wrapper for a subset of ICU.

ICU is a mature, widely used set of C/C++ and Java libraries providing Unicode and Globalization support for software applications. ICU is widely portable and gives applications the same results on all platforms and between C/C++ and Java software.

NuGet version (icu.net) Build, Test and Pack

Usage

This library provides .NET classes and methods for (a subset of) the ICU C API. Please refer to the ICU API documentation. In icu.net you'll find classes that correspond to the C++ classes of ICU4C.

Although not strictly required it is recommended to call Icu.Wrapper.Init() at the start of the application. This will allow to use icu.net from multiple threads (c.f. ICU Initialization and Termination). Similarly, it might be beneficial to call Icu.Wrapper.Cleanup() before exiting.

Sample code:

    static class Program
    {
        public static void Main(string[] args)
        {
            Icu.Wrapper.Init();
            // Will output "NFC form of XA\u0308bc is XÄbc"
            Console.WriteLine($"NFC form of XA\\u0308bc is {Icu.Normalizer.Normalize("XA\u0308bc",
                Icu.Normalizer.UNormalizationMode.UNORM_NFC)}");
            Icu.Wrapper.Cleanup();
        }
    }

Building

To build the current version of icu-dotnet you'll need .NET 8.0 or .NET 10.0 installed.

icu-dotnet can be built from the command line as well as Visual Studio or JetBrains Rider.

Running Unit Tests

You can build and run the unit tests by running:

dotnet test source/icu.net.sln

or, if wanting to run tests on just one specific .net version (v8.0 in this example):

dotnet test source/icu.net.sln -p:TargetFramework=net8.0

Android

Android support is limited. Only collation APIs are supported for now. Other ICU functionality (normalization, break iteration, locale handling, and so on) is not yet available on Android. The Android test project references the full icu.net.tests suite, but CI and the helper scripts intentionally run only collation tests plus Android-specific smoke/diagnostic tests.

Prerequisites:

  • .NET 10 SDK with the MAUI Android workload: dotnet workload install maui-android
  • Android SDK (ANDROID_HOME set) with an emulator running or a USB device attached
  • The Icu4c.Android.Fw.Lib NuGet package (FieldWorks ICU natives + data). The Android test project already references it. icu.net reads the ICU major version from the bundled icudtNl.dat asset at runtime, so bumping that native package does not require rebuilding icu.net. Optionally call Icu.Wrapper.ConfineIcuVersions(70) before Init() to pin a version, as on other platforms.

Run the filtered Android device test suite (collation + Android-specific tests only):

.\scripts\run-android-tests.ps1

On Linux/macOS (or CI), use bash scripts/ci-android-tests.sh instead. Both scripts apply the same test filter as CI and print a reminder that only the filtered subset is expected to pass.

Linux and macOS

It is important for icu.net.dll.config to be bundled with your application when not running on Windows. If it doesn't copy reliably to the output directory, you might find adding something like the following to your csproj file will resolve the issue. Note that the version number in the path must match the version number of icu.net that is referenced in the project.

<ItemGroup>
  <None Update="$(NuGetPackageRoot)\icu.net\2.9.0\contentFiles\any\any\icu.net.dll.config">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
</ItemGroup>

Docker

icu-dotnet depends on libc dynamic libraries at run time. If running within Docker, you may need to install them, for example:

FROM mcr.microsoft.com/dotnet/aspnet:3.1

# Install system dependencies.
RUN apt-get update \
    && apt-get install -y \
        # icu.net dependency: libdl.so
        libc6-dev \
     && rm -rf /var/lib/apt/lists/*

...

ICU versions

Linux

icu-dotnet links with any installed version of ICU shared objects. It is recommended to install the version provided by the distribution. For example:

OS ICU
Ubuntu 22.04 (Jammy) 70
Ubuntu 24.04 (Noble) 74
Ubuntu 26.04 (Resolute) 78
Debian 12 (Bookworm) 72
Debian 13 (Trixie) 76

If the version provided by the Linux distribution doesn't match your needs, Microsoft's ICU package includes builds for Linux.

Windows

Rather than using the full version of ICU (which can be ~25 MB), a custom minimum build can be used. It can be installed by the Icu4c.Win.Min nuget package. The full version of ICU is also available as Icu4c.Win.Full.Lib and Icu4c.Win.Full.Bin.

Microsoft also makes the full version available as Microsoft.ICU.ICU4C.Runtime.

What's in the minimum build
  • Characters
  • ErrorCodes
  • Locale
  • Normalizer
  • Rules-based Collator
  • Unicode set to pattern conversions

macOS

macOS doesn't come preinstalled with all the normal icu4c libraries. They must be installed separately via a package manager such as Homebrew or MacPorts.

# Homebrew (more common)
brew install icu4c

# MacPorts
sudo port install icu

icu.net automatically searches the standard Homebrew and MacPorts installation directories, so no extra configuration is needed after installing via either package manager.

Troubleshooting

  • make sure you added the nuget package icu.net and have native ICU libraries available.
  • the binaries of the nuget packages need to be copied to your output directory. For icu.net this happens by the assembly reference that the package adds to your project. The binaries of Icu4c.Win.Min are only relevant on Windows. They will get copied by the Icu4c.Win.Min.targets file included in the nuget package.

On Windows, the package installer should have added an import to the *.csproj file similar to the following:

<Import Project="..\..\packages\Icu4c.Win.Min.54.1.31\build\Icu4c.Win.Min.targets"
    Condition="Exists('..\..\packages\Icu4c.Win.Min.54.1.31\build\Icu4c.Win.Min.targets')" />

Contributing

We love contributions! The library mainly contains the functionality we need for our products. If you miss something that is part of ICU4C but not yet wrapped in icu.net, add it and create a pull request.

If you find a bug - create an issue on GitHub, then preferably fix it and create a pull request!

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (11)

Showing the top 5 NuGet packages that depend on icu.net:

Package Downloads
SIL.WritingSystems

SIL.WritingSystems contains classes for managing and persisting writing systems using the Locale Data Markup Language (LDML) format. This library also contains classes for processing IETF (BCP-47) language tags and accessing the SIL Locale Data Repository (SLDR).

SIL.Lib

SIL.Core.dll, SIL.WritingSystems.dll, SIL.Scripture.dll

SIL.Windows.Forms.Keyboarding

The SIL.Windows.Forms.Keyboarding library provides cross-platform functionality for keyboard selection and switching in Windows Forms applications. Currently, this library supports system and Keyman keyboards on Windows, and X keyboard extension (XKB) and Intelligent Input Bus (IBus) keyboards on Linux.

SIL.WritingSystems.Tests

Unit tests for SIL.WritingSystems

ParatextData

Dll for use by third party applications needing to access Paratext's data. Compatible with SIL.Lib 12.0.x (required). Backwards compatible with data from Paratext 8.0 and 9.x. NOTE: This version of ParatextData is built using a AnyCPU configuration, but certain projects will not open correctly when run as 32-bit because of dependencies on native 64-bit libraries.

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on icu.net:

Repository Stars
lindexi/lindexi_gd
博客用到的代码
sillsdev/FieldWorks
FieldWorks is a suite of software tools for language and cultural data, with support for complex scripts.
Version Downloads Last Updated
4.0.1-beta.1 50 9/25/2026
4.0.0 150 9/23/2026
4.0.0-beta.38 59 9/23/2026
3.0.3-beta.35 56 9/23/2026
3.0.3-beta.34 109 9/23/2026
3.0.3-beta.33 65 9/23/2026
3.0.3-beta.32 58 9/22/2026
3.0.3-beta.31 53 9/22/2026
3.0.3-beta.27 54 9/22/2026
3.0.3-beta.22 55 9/18/2026
3.0.3-beta.19 54 9/18/2026
3.0.3-beta.7 107 6/11/2026
3.0.3-beta.6 97 6/11/2026
3.0.3-beta.5 78 6/10/2026
3.0.3-beta.4 86 6/10/2026
3.0.3-beta.3 82 6/8/2026
3.0.3-beta.2 78 6/8/2026
3.0.3-beta.1 88 6/3/2026
3.0.2 34,628 6/2/2026
3.0.1 140,164 2/21/2025
Loading failed

Changes since version 3.0.1

Added:
- NuGet package now includes the XML documentation file, enabling IntelliSense summaries in Visual Studio.
- In Character class, added all enums from Unicode's uchar.h that were missing:
 UBidiPairedBracketType, UBlockCode, UEastAsianWidth, UPropertyNameChoice, UJoiningType,
 UJoiningGroup, UGraphemeClusterBreak, UWordBreakValues, USentenceBreak, ULineBreak,
 UHangulSyllableType, UIndicPositionalCategory, UIndicSyllabicCategory, UIndicConjunctBreak,
 UVerticalOrientation, UIdentifierStatus, UIdentifierType.
- Added net10.0 target framework.

Changed:
- **BREAKING CHANGE:** Replaced the `net451` target framework with `net462`, matching the
 framework already used by current consumers (e.g. libpalaso, LibChorus) and remaining the
 nearest compatible target for others (FieldWorks, SayMore, HearThis). Any consumer targeting
 `net461` or lower will no longer resolve a compatible .NET Framework build of this package
 (falling back to the `netstandard2.0` build instead, if their tooling supports it). The
 `net461`-targeted test/tooling projects in this repo were bumped to `net462` to match.
- Upgraded `System.ValueTuple` from 4.5.0 to 4.6.2.
- Unified `Microsoft.Extensions.DependencyModel` on version 10.0.9 across all target frameworks:
 it now officially supports `net462`, so the old net451-era pin to 2.1.0 (and the accompanying
 `Newtonsoft.Json` override) is no longer needed.
- Removed the explicit `Microsoft.SourceLink.GitHub` `PackageReference`: verified that the .NET
 SDK (8.0+) now embeds correct `raw.githubusercontent.com` source link mappings for GitHub repos
 without it — confirmed by inspecting the packed `.snupkg` PDBs for all four target frameworks.
- Removed the `System.IO.FileSystem` / `System.IO.FileSystem.Primitives` 4.3.0 references from
 the test project: netstandard1.x-era facades, both deprecated on nuget.org, no longer needed
 now that the lowest test target is `net462`.
- Replaced the legacy TeamCity-oriented `build/icu-dotnet.proj` MSBuild file with plain `dotnet`
 CLI scripts (`build/TestBuild.sh`, `build/TestPack.sh`), matching what CI already runs. This
 build path had not been used by CI for a long time (CI now calls `dotnet build`/`test`/`pack`
 directly) and TeamCity itself was decommissioned for this project a while back. The scripts
 test each target framework explicitly and only run the `net462` tests on Windows (matching
 CI's platform gating, since .NET Framework tests can't run on macOS/Linux); `set -e` ensures
 a build or test failure stops the script instead of `dotnet pack` silently masking it.

Fixed:
- Fixed `RuleBasedCollator.GetSortKey` silently returning corrupted keys when called
 concurrently on one collator: each call now gets its own sort key buffer.
- Fixed `Transliterator.Transliterate` throwing `OverflowException` for characters that expand
 greatly during transliteration (e.g. U+FDFA ﷺ): the method now retries with a larger buffer
 on `BUFFER_OVERFLOW_ERROR` instead of immediately throwing.
- Fixed `Wrapper.ConfineIcuVersions` being ignored during library discovery: `CheckDirectoryForIcuBinaries`
 now filters candidates to the confined version range before selecting the highest match.
- Fixed macOS crash at process exit (.NET 6+): `u_cleanup()` and `NativeLibrary.Free` are now
 skipped on macOS so dyld does not fire ICU's destructor against already-cleaned state. Also
 fixed an independent ordering bug on all platforms: `u_cleanup()` was previously called after
 `ResetIcuVersionInfo()`, causing the runtime to look up the nonexistent symbol `u_cleanup_0`
 and silently skip the call.
- Fixed ICU library discovery on macOS: `LocateIcuLibrary` now falls back to Homebrew
 (`/opt/homebrew/opt/icu4c/lib` on Apple Silicon, `/usr/local/opt/icu4c/lib` on Intel) and
 MacPorts (`/opt/local/lib`) when no bundled ICU is found. Bundled ICU (in the assembly
 directory or `runtimes/` subdirectories) is always preferred over system installations.
- Removed no-op `LD_LIBRARY_PATH` manipulation on macOS. (Changing it to the mac-specific
 `DYLD_LIBRARY_PATH` would also be a no-op, because SIP strips all `DYLD_*` variables from
 protected processes at launch, so setting it at runtime has no effect.)
- Fixed `umsg_open` `locale` parameter marshaling from Unicode to ANSI, correcting ICU message
 formatting on macOS where the locale string was being passed as wide characters.
- Fixed `SafeEnumeratorHandle` and `Transliterator.SafeTransliteratorHandle` finalizers to
 silently swallow exceptions during .NET shutdown, when ICU may no longer be accessible.
- Fixed test teardown instability on macOS: `NativeMethodsHelperTests` now deletes dummy ICU
 files before resetting version state (preventing "Can't load ICU library (version 90)" failures
 in subsequent tests); `IcuWrapperTests` now skips `ConfineIcuVersions` on macOS, where
 `NativeLibrary.Free` is omitted so the library stays resident and version constraints must not
 be reset against it.
- Fixed `IsInitialized` not being reset on cleanup paths that skip `u_cleanup()`: it was a side
 effect of `u_cleanup()` rather than an explicit step, so any code path that skipped
 `u_cleanup()` (e.g. macOS on .NET 6+) would leave `IsInitialized = true` after cleanup.
 `IsInitialized = false` is now set unconditionally in `Cleanup()` and removed from `u_cleanup()`.
- Fixed `MessageFormatter.Format` crashing on ARM64 (.NET only): it now throws
 `PlatformNotSupportedException` instead. The AAPCS64 calling convention passes variadic
 float arguments through integer registers, incompatible with .NET's fixed-slot P/Invoke
 marshaling of the variadic C function `umsg_format`.
- Fixed `Transliterator.GetDisplayName` and `GetIdsAndNames` on ARM64: both now catch the
 `PlatformNotSupportedException` from `umsg_format` and fall back to the English
 "source to target" display name form. On non-ARM64 Unix with ICU 74+, where a calling-convention
 mismatch produces empty output rather than a crash, the existing `IsNullOrEmpty` fallback now
 covers macOS in addition to Linux.
- Fixed `Transliterator.GetDisplayName` returning empty display names on Linux ICU 74+.
 `umsg_format` is a variadic C function; on Linux ICU 74+ a calling-convention mismatch
 causes the `double` argument to be read as 0, producing empty output from the
 `TransliteratorNamePattern` choice format. The method now falls back to constructing
 the display name directly from the localized source and target script names.
- Fixed regex patterns in `NativeMethodsHelper` for Linux (`libicu*.so.*`) and macOS
 (`libicu*.dylib`): unescaped `.` matched any character instead of a literal dot.
- Fixed `NativeMethodsHelper` combined regex: `$` end-anchor now applies to all three
 platform alternatives, not only the macOS branch.
- Fixed `NativeMethodsHelper` regex patch-version segments: `(\.[0-9])*` changed to
 `(\.[0-9]+)*` to allow multi-digit patch components.
- Fixed `TimeZoneTests.GetTZVersionTest`: version pattern is now anchored (`^[0-9]{4}[a-z]$`)
 so it validates the full string rather than a substring.

Deprecated:
- In Character class, added \[Obsolete\] attribute to enum members UDecompositionType.COUNT and
 UNumericType.COUNT.

Removed:
- **BREAKING CHANGE:** Dropped the `net40` target framework. A GitHub code search across
 sillsdev's repos found no remaining consumers, and nothing in icu-dotnet's own test suite
 exercised it either, but any project still building against `net40` specifically will no
 longer find a compatible asset in this package.
- Removed dead `#if NET40` / `#if !NET40` conditional code (and the comments explaining it) from
 `NativeMethods.cs`, `NativeMethodsHelper.cs`, `NativeMethodsTests.cs`, `NativeMethodsHelperTests.cs`,
 `CharacterTests.cs`, and `LocaleTests.cs`, now that `net40` is no longer a target framework.
 Also updated remaining `net461`/`4.5.1`-specific comments to reflect the `net462` retarget.
- Removed `build/icu-dotnet.proj`, `build/NuGet.targets`, and `build/TestInstallerBuild.bat`
 (the latter was unrelated leftover cruft for building a different repository), along with the
 `SIL.BuildTasks` and `NUnit.Console` dependencies that only existed to support that build path.

Security:
- Upgraded `Microsoft.Extensions.DependencyModel` from 2.0.4 to 10.0.9 on non-.NET-Framework
 targets, eliminating the transitive dependency on `Newtonsoft.Json` 9.0.1 (high severity
 vulnerability).
- Upgraded `SIL.ReleaseTasks` to 4.0.0, which upgrades its own `SIL.Core` dependency to bring
 `Newtonsoft.Json` to 13.0.1 — past the vulnerability (GHSA-5crp-9r3c-p9vr) — and no longer
 exports any transitive dependencies publicly. This was never consumer-facing, since the
 reference to `SIL.ReleaseTasks` already uses `PrivateAssets="all"`.

See full changelog at https://github.com/sillsdev/icu-dotnet/blob/master/CHANGELOG.md.