On this page

27. .NET interoperability

27.1 Ordinary CLR binding

CS-INTEROP-001. DirectSharp directly binds ordinary CLR types and APIs through project references. Imported class/interface/enum/delegate types, generics, overloads, extension methods, attributes, awaitables and expression trees keep their actual CLR contracts. A wrapper or feature is not required to use a normal .NET library.

public action SerializeNames(names as Global.System.Collections.Generic.List <of String>)
    returns String
    return Global.System.Text.Json.JsonSerializer.Serialize(names)
end action

Case-insensitive source identifiers do not rewrite emitted public API names or arbitrary runtime string/key data. Casing-only imported overload/member collisions that cannot be disambiguated are diagnosed rather than silently selected.

A nested CLR type keeps its declaring type in its name: for example, System.Environment.SpecialFolder is the enum accepted by Environment.GetFolderPath. A namespace import can shorten that spelling to Environment.SpecialFolder; it does not change the CLR type, accessibility or overload contract. The executable report directory example uses this API directly.

27.2 Semantic boundaries

CS-INTEROP-002. Source conveniences preserve imported operator/API behavior where the specification assigns that boundary. Authored String comparisons, authored nullable arithmetic, logical async results and scoped result selectors must not be implemented by replacing every operation with its superficially similar C# spelling. Conversely, an imported operator must not gain DirectSharp's authored-type policy merely because it is called from DirectSharp.

Task is the normal authored async ABI. Imported ValueTask stays ValueTask. Delegates and expression trees use the target API's callable contract. A query provider interprets its expression representation; ordinary CLR calls remain calls, not an invented database language.

CLR access, generic constraints, attribute targets, reference passing and override/interface compatibility remain enforced. Low-level unsafe/function-pointer syntax, new backend guarantees and package-specific DSLs are not implied by ordinary interoperability.

27.3 Public representation

Stable source intent should produce ordinary CLR representations: classes/interfaces, ValueTuple where specified, enums, events, delegates, IEnumerable<T>/IAsyncEnumerable<T>, Tasks and ordinary metadata. Compile-time abstractions such as class kinds, features and wrappers do not become a new runtime object model. Necessary compiler metadata may supplement CLR declarations for needs and separate compilation without changing their source meaning.


Specification contents · Previous: 26. Project model · Next: 28. Reference C# lowering