kotlin-native-nuget Help

Enums

A Kotlin enum class becomes a C# enum with matching ordinal values. Members declared on the enum class (properties, methods) become C# extension methods, since a C# enum can't carry behavior itself.

enum class Mood { HAPPY, SLEEPY, GRUMPY; val description: String get() = when (this) { HAPPY -> "The cat is happy and content." SLEEPY -> "The cat is sleepy and ready for a nap." GRUMPY -> "The cat is grumpy and doesn't want to be disturbed." } }
Mood mood = Mood.Happy; // HAPPY -> Happy, ordinal 0 string description = mood.Description(); // extension method

Entries rename from Kotlin's SCREAMING_SNAKE_CASE to C#'s PascalCase. A property or method typed with the enum, in any parameter, return, or getter/setter position, binds like any other enum-typed member: var mood: Mood becomes a settable Mood property.

Nullable

A bare Mood? (not wrapped in a value class) binds as C# Mood? at every ordinary position: property, constructor/method/extension/top-level parameter, and return. null stays distinct from every ordinal, including Mood.Happy at ordinal 0.

class MoodJournal(observed: Mood?) { var currentMood: Mood? = null fun soothe(mood: Mood?): Mood? = if (mood == Mood.GRUMPY) Mood.SLEEPY else mood }
using var journal = new MoodJournal(null); journal.CurrentMood = Mood.Grumpy; Mood? soothed = journal.Soothe(Mood.Grumpy); // Mood.Sleepy

A top-level function or property getter returning Mood? is evaluated twice when it returns a value. Keep those functions and getters free of side effects and ensure their result stays stable between evaluations. Ordinary instance methods, such as Soothe above, evaluate once.

As a collection component

A bare enum crosses a List/Map/Set element, key, or value (nullable included) as its int ordinal, both ways.

enum class Mood { CALM, ANXIOUS, PLAYFUL } class MoodLedger { fun logMoods(moods: List<Mood>): String = moods.joinToString(",") fun moodsOnFile(): List<Mood> = listOf(Mood.CALM, Mood.PLAYFUL) }
using var ledger = new MoodLedger(); ledger.LogMoods(new[] { Mood.Calm, Mood.Playful, Mood.Calm }); IReadOnlyList<Mood> moods = ledger.MoodsOnFile();

This also makes a bare-enum collection property settable, not get-only; see Collections: Mutable collection properties. A nested collection element (List<List<Mood>>) has no representation and is skipped; see Collections.

Nested enums

An enum class nested inside an admitted owner (a non-generic, non-inner class, object, or interface, at any depth; see Classes and objects: Owners ADR-134 admits) is declared as a real nested C# enum, Outer.Kind. Its extension methods are hoisted to a top-level class instead (OuterKindExtensions, named for the whole enclosing chain), because C# forbids an extension method inside a nested class (CS1109).

class NestedModeOwner { enum class Mode { ON, OFF } var setting: Mode = Mode.ON fun set(mode: Mode) { this.setting = mode } fun current(): Mode = setting }

Name a property that holds the nested enum something other than the enum's own name (setting, not mode): PascalCasing a mode property to Mode would collide with the nested type Mode itself (CS0102).

A nested enum under a still-deferred owner (an inner class, a generic, or another enum class; see Classes and objects: Nested types) is not declared: the declaration itself is skipped with SKIPPED_NESTED_DECLARATION, and a parameter, return, or property typed with it is skipped with SKIPPED_UNSUPPORTED_TYPE/SKIPPED_UNSUPPORTED_PROPERTY naming UNDECLARED_ENUM; the owning class still generates with its other members.

Last modified: 19 September 2026