# Platform Notes

> USearch for C#

### Interop

Every entry point is declared with `[LibraryImport]`, so the marshalling stubs are source-generated and compiled in rather than reflected at runtime, and the assembly stays trimmable and ahead-of-time compilable.
Every verb takes one argument struct, as the C interface does, and holds a reference on each `SafeHandle` the struct names for the length of the C call, so a finalizer can never free a handle out from under a running verb, and the free of one a deferred call still names waits for that call.

### What This Binding Does Not Expose

- __Progress handlers.__
  Every verb passes the C `progress` callback as null, so a long `Insert`, `Refine`, `Absorb`, `Split`, `Sample` or `Save` runs to its end, and `Status.Cancelled` never arises.
- __Deferred cursors and streams.__
  `Cursor` and `SearchStream` pull blocking, so a `DenseIndexDeferredOn` lacks them.
- __Constructors on receivers.__
  The constructors address no index yet, so no receiver offers them; the ones the C interface lets fan out take an `executor` argument and run on the caller's thread without one.
- __Version numbers and class names.__
  `usearch_version` and the CPU and GPU class spellings stay unbound; `USearchCapabilities.Version()` answers the version as text.

### Design

- __A thin layer over the C ABI.__
  Every name follows `include/usearch/`: a C verb `usearch_dense_<verb>` is a `<Verb>` method here, and enums mirror C enums, never strings.
- __The receiver chooses, the verb stays.__
  The index runs a verb on the calling thread, `On(executor)` blocks on an executor, and `Deferred(executor)` submits it, all with the same arguments.
- __Deferred calls use the language's own idioms.__
  `Status` polls through `usearch_outcome_status`, `Wait()` blocks through `usearch_outcome_wait`, and `await` hands that wait to the thread pool.
- __No life of its own.__
  The binding starts no threads and keeps no queues; releasing a `Deferred` rides `Dispose` and `using`, which waits for the call first.
- __Arenas are lent and reused, never shared.__
  Every output whose length scales with the call lands in an arena the caller passes; a view the arena's next call outdated throws rather than reading rewound memory.
- __Nothing costs anything until it is used.__
  Submitting a call allocates nothing, and an arena allocates only when a call writes into it.
- __Blocking calls stay on the stack.__
  A blocking call keeps its outputs on the stack, fixes its buffers in place without a pinning handle, and answers a view by value; a deferred one allocates its handle and one pinned outputs struct.
- __Exceptions never cross the native boundary.__
  A predicate or `rowOf` delegate that throws is captured on the worker thread and rethrown with its own type once the call is final.

