kotlin-native-nuget Help

Objects and companions

A Kotlin object becomes a C# static class: no instance, no constructor, its members reached directly through the type. A companion object's members land as static members directly on the enclosing C# class, not on a separate Companion type. A data object nested inside a sealed class becomes a sealed subclass instead; see Interfaces, abstract and sealed classes. An object can also own a nested type the same way a class can; see Nested types.

For this declaration in CatRegistry.kt:

object CatRegistry { private val cats: MutableList<String> = mutableListOf() fun register(name: String) { cats.add(name) } fun count(): Int = cats.size }

Call it from C# through the type; there is nothing to construct:

CatRegistry.Register("Oreo"); CatRegistry.Register("Mylo"); int count = CatRegistry.Count(); // 2

Object methods are PascalCased and their returns marshalled exactly like class methods; see Classes and objects.

Companion objects

A companion's members are static members on the enclosing class itself:

class Cat( name: String, val lives: Int = 9, ) : Animal(name) { companion object { const val SPECIES: String = "Felis catus" val defaultBreed: String = "Domestic Shorthair" fun fromName(name: String): Cat = Cat(name) } }
string species = Cat.Species; // "Felis catus" string breed = Cat.DefaultBreed; // "Domestic Shorthair" using var cat = Cat.FromName("Whiskers");

There is no separate Cat.Companion class in the generated output.

Method overloads

Two or more same-named members on an object or a companion object generate one natural C# overload set, resolved by parameter type like any other C# overload, including an Int overload beside an enum overload:

object Parlour { fun rate(stars: Int): String = "the parlour is rated $stars" fun rate(coat: Coat): String = "the parlour grooms ${coat.name.lowercase()} coats" }
string byStars = Parlour.Rate(10); // "the parlour is rated 10" string byCoat = Parlour.Rate(Coat.Tuxedo); // "the parlour grooms tuxedo coats"

See Method overloads in Classes and objects for the same rule on class methods, top-level functions, and extension functions.

Method default parameters

A trailing run of defaulted parameters on an object or companion member generates one overload per omitted trailing default, each using the Kotlin default for the parameters it drops:

object Kibble { fun scoop(flavour: String, scoops: Int = 2): String = "$scoops scoops of $flavour" }
string oneFlavour = Kibble.Scoop("tuna"); // "2 scoops of tuna"; scoops defaults to 2

Only a trailing run of defaults gets an omitting overload: a defaulted parameter followed by a non-defaulted one does not, so pass it explicitly. A trailing default the bridge cannot carry costs only that arity.

object Switchboard { fun patch(level: Int = 0, events: Flow<Int>? = null): String = "patch $level/${events?.toString() ?: "-"}" }
Switchboard.Patch(); Switchboard.Patch(3);

The events arity does not exist. See Method default parameters for the full rule.

Last modified: 19 September 2026