On this page

C# reference implementation

The C# patterns on this page explain how to preserve DirectSharp semantics: evaluation order, effective defaults, ownership, failure and coordination. They are representative translations, not alternative definitions of the language.

DirectSharp semantics define the program. Reference C# explains how a .NET backend can preserve them: what it must evaluate once, where it must wait, which value it publishes and who owns cleanup. Temporary names and helper containers shown here are illustrative, not public APIs.

Find an implementation topic

Concern Detailed contract and examples Essential cases
Names and CLR binding Syntax, .NET binding Case-only collisions, Global qualification, overload ambiguity, imported metadata
Types/defaults/conversions Types, specification chapter 4 Actual absence, effective defaults, nullable values, checked conversion and imported operators
Expressions and control flow Reference, chapter 7 Once-only subjects, short-circuiting, final take, cleanup on targeted exit
Actions/callables Chapter 8 Definite result assignment, delegate versus expression tree, source parameter names
Classes/class kinds/data Objects, customer lowering Properties versus fields, constructor inputs, class-kind expansion, explicit interface intent
Contracts and entry snapshots Chapter 12 Entry capture order, source suffix/argument attribution, ensure after successful cleanup
Exceptions and resources Resources, chapter 13 Rethrow identity, partial acquisition, reverse cleanup, async disposal, LastAttempt
Collections/consumption Chapter 15, library Deferred shortage, call-time optional absence, live emptiness, borrowed cursors
Text/patterns Chapter 14, chapter 16 UTF-16 versus scalars, source-order interpolation, named capture types and scope
Async/concurrency Concurrency, chapter 17 Cancellation binding, linked producers, joins, failure priority, limits and publication
Lazy/event support Lazy state and publication, chapter 18, events and subscription lifetime Exactly-once forcing, recursion, cached failure, callable identity and handler lifetime
Dependencies/services Chapter 20, .NET ownership Required needs, exact keys, root safety, explicit scopes and borrowed services
Metadata/extensions/tooling Chapters 21–28 CLR attributes, deterministic preprocessing/wrappers, restricted engines and source maps

The library plan separates ordinary CLR APIs from support that may stay private to generated code. A public helper is useful only when its contract is actually part of the library design.

Preserve values and evaluation order

Case-insensitive source binding happens before C# emission. Two CLR members distinguishable only by case can be ambiguous to DirectSharp; choosing the spelling that happens to match generated C# is not a valid repair. The compiler must emit a diagnostic where the source cannot bind uniquely.

Normal String equality has its own contract, separate from identifier lookup and the comparers used by imported dictionaries. For language ordinal-ignore-case String equality, an appropriate reference operation is:

bool same = string.Equals(left, right, StringComparison.OrdinalIgnoreCase);

Here left/right are already evaluated String operands. An imported Dictionary using StringComparer.Ordinal keeps exact String keys. Required keyed service lookup also keeps exact keys; the compiler must not lowercase arbitrary application data.

Likewise, CLR default(string) is null, while DirectSharp's effective String default is empty. Substituting default(T) everywhere would lose that distinction. Conditional extraction can preserve actual absence by using nullable CLR representations rather than filling in zero:

// GetCustomer() supplies a nullable application Customer with Age/Email members.
var source = GetCustomer();
int? age = source is null ? null : source.Age;
string? email = source is null ? null : source.Email;

This illustrates a once-captured let_if from source and independent extracted locals. A present source still evaluates its member expressions normally, in written order; getter failures propagate. Strict let from instead requires the source to be present. Unsupported CLR absence representations must be diagnosed rather than replaced with invented wrappers or boxed defaults.

Source case Backend obligation
Coalescing with present zero/false/empty String Keep the present value; do not run fallback
Coalescing with an empty sequence Keep the sequence; empty is not absence
Direct parameter ?? throw Preserve contextual ArgumentNullException attribution
Other absent expression ?? throw Use the established NullReferenceException category
Conditional/safe access Evaluate each reached part once; skip later work only on the specified absent path
Custom getter/indexer failure Propagate the failure rather than treating every failure as absence
Imported numeric operator Retain that CLR operator's semantics rather than applying authored default substitution

See types and defaults and extraction rules.

Property reads versus required operations

For ordinary read chains, capture each reached receiver and skip later getters after absence. This member fragment assumes a Customer with Address.City and illustrates one evaluation of an application-supplied source factory:

private static string? ReadCity(Func<Customer?> source)
{
    var customer = source();
    var address = customer is null ? null : customer.Address;
    return address is null ? null : address.City;
}

C# conditional access can express the same applicable pattern, but its punctuation is a backend technique, not required DirectSharp source. For a possibly absent Customer with Decimal CreditLimit, produce decimal? and then apply ?? 0m when a nonnullable fallback result is requested. Do not replace a missing value with its effective numeric/String default during the read itself.

The required call/write path is different: retain the native missing-receiver failure. Do not wrap an entire call in a catch for NullReferenceException, because a present receiver's method body may legitimately throw that same exception. Indexing likewise keeps its own required receiver/bounds/key contract. Conditional use_if skips on a missing qualification path; it does not suppress a reached getter's failure.

PropertyReadChecks exercises absent roots/intermediates, once-only source/getters, real zero/empty/null values, nullable fallback and original getter/body failure identity. It also checks required call/write/index failures. These are native C# patterns for the frozen read rules, not compiler diagnostic or generated-code tests.

Capture results before cleanup; publish after it

A value-producing resource scope has two separate events: computing the prospective value and successfully completing cleanup. This simple synchronous pattern makes the ordering visible:

public string ReadReport(string path)
{
    string captured;
    using (var reader = new System.IO.StreamReader(path))
    {
        captured = reader.ReadToEnd();
    }
    return captured;
}

If opening or reading fails, no value is returned. If disposal throws after a successful read, that failure also prevents return. Multiple resources require left-to-right acquisition and reverse cleanup of successfully acquired resources; nested C# using scopes can express this. A later acquisition failure must still clean earlier resources.

In an asynchronous execution context, generated C# prefers the resolved static IAsyncDisposable contract and awaited cleanup; otherwise it uses available IDisposable. This includes inferred async ordinary actions and async dispose bodies. Async-only owned cleanup can require permitted ordinary action inference; a dual-interface resource alone does not make an otherwise synchronous body async. Generated cleanup needs no additional source await, while ordinary async calls do. A statically IDisposable-only view selects synchronous cleanup even if the runtime object also supports asynchronous disposal. Fixed synchronous code requires IDisposable; an async-only resource is a compile-time error, without a blocking bridge. Mixed groups preserve reverse order with each resource's required mechanism. Borrowed needs, caller-owned consumable sources and unrelated disposable members do not acquire ownership just because they appear in a scope.

Action-level ensure checks follow successful body and finally/resource completion. They must not be put in a C# finally block, which would run on exceptional exits too. Capture a return expression once, finish required cleanup, evaluate successful-exit postconditions and then return the captured value. A failed cleanup or postcondition prevents publication.

Entry snapshots are another boundary. Capture each distinct eligible old_value_of source at action entry in first occurrence order, before require checks. Repeated references reuse that capture; a failure in an earlier getter stops later captures. Constructor entry follows its required generated initialization. A body local that does not exist at entry cannot be made into an entry source by moving its evaluation.

Keep sequence absence separate from default values

The recorded DirectSharp First/Last accessors return actual nothing for an empty sequence. For a present Integer zero, Boolean false or empty String, they return that item. Native LINQ First()/Last() instead throw on empty input, while FirstOrDefault()/LastOrDefault() return the element type's CLR default. Neither substitution preserves the complete DirectSharp contract for every element type.

Source Required selection value Naive native default selection
Empty Integer sequence nothing Integer 0
Integer sequence containing 0 Integer 0 Integer 0
Empty Boolean sequence nothing Boolean false
Boolean sequence containing false Boolean false Boolean false
Empty String sequence nothing null
String sequence containing empty String Empty String Empty String

For a known nonnullable value type, lifting elements before native selection is one ordinary .NET technique:

IEnumerable<int> values = Array.Empty<int>();
int? first = values.Select(static value => (int?)value).FirstOrDefault();
int? last = values.Select(static value => (int?)value).LastOrDefault();

IEnumerable<int> zeros = new[] { 0 };
int? presentZero = zeros.Select(static value => (int?)value).FirstOrDefault();

Here first/last are null and presentZero has value 0. The two selections are independent calls, each with its own traversal; this is not a recipe for reading a forward-only source twice. Last must reach exhaustion on a general enumerable and cannot finish on an endless one. This example is native LINQ, not a new DirectSharp export or an IQueryable translation promise.

An unconstrained C# T? annotation does not make every value-type instantiation Nullable<T>. A generic helper returning source.FirstOrDefault() as T? still returns zero for an empty Integer sequence. A possible private backend strategy keeps presence and payload separate until it constructs the caller's appropriate absence-capable result:

private static bool TryReadFirst<T>(IEnumerable<T> source, out T item)
{
    ArgumentNullException.ThrowIfNull(source);
    using var iterator = source.GetEnumerator();
    if (!iterator.MoveNext())
    {
        item = default!;
        return false;
    }
    item = iterator.Current;
    return true;
}

private static bool TryReadLast<T>(IEnumerable<T> source, out T item)
{
    ArgumentNullException.ThrowIfNull(source);
    using var iterator = source.GetEnumerator();
    item = default!;
    bool found = false;
    while (iterator.MoveNext())
    {
        item = iterator.Current;
        found = true;
    }
    return found;
}

These are private C# member fragments, not selected public TryFirst/TryLast declarations. They require a nonnull synchronous enumerable and illustrate one traversal with no Count pass, no default-value sentinel and disposal before successful return. The false branch's default payload is private storage, never the published selected value. Iterator acquisition, movement, Current and disposal failures propagate; no catch turns them into absence. A disposal failure prevents a successful call result even if the prospective out payload has already been written. There is no rollback guarantee for iterator side effects or caller-visible storage.

At a bound Integer use, the caller can turn false into null and true into an int? holding the selected item. Reference and already-nullable elements retain their actual values; an existing null item remains nothing, without introducing a third public optional state. The final First/Last CLR export/binding, a native helper's null-source policy and asynchronous-source applicability still require a concrete API account. Ordinary property reads already follow the automatic read-chain contract; these private function guards do not override that source rule. The API catalogue retains the binding boundary.

The isolated reference fixture checks these native patterns with empty/default-valued inputs, nullable/reference payloads, one-use sources, traversal limits and original iterator/cleanup failures. It does not execute DirectSharp member binding.

Bind the selected result to its CLR type

Bind the element and result types before emitting selection. A private Boolean/payload pair can carry the information while the caller produces the actual CLR result; it is not the public result type.

Bound element Absence-capable result Important case
Nonnullable Integer, Boolean, Guid or another compatible struct Actual Nullable of that type A real zero/false/default struct remains an item
String or another reference The same CLR reference type, capable of null Empty String remains empty; preserve object identity
Already Nullable of Integer That same Nullable type No Nullable of Nullable or third public state
Unconstrained T in a fixed CLR method signature No universal Nullable<T> can be inferred Resolve a representable contract; never publish default(T) as empty-source absence
Task or ValueTask containing an unconstrained T? payload The operation's actual constructed payload type An async envelope does not make an int payload nullable

The public action can state a known result contract deliberately. These examples select totals without treating zero as missing:

public class InvoiceBoundary
    public static action FirstTotal(
        totals as Global.System.Collections.Generic.IEnumerable <of Decimal>
    )
        returns Global.System.Nullable <of Decimal>
        return totals.First
    end action

    public static action RequireFirstTotal(
        totals as Global.System.Collections.Generic.IEnumerable <of Decimal>
    )
        returns Decimal
        return totals.First ?? throw
    end action
end class

FirstTotal preserves missing source/empty selection as nothing. RequireFirstTotal uses the existing contextual throw, producing NullReferenceException for absence, including a missing source read. It does not infer a helper-specific exception. A present zero passes both policies. Iterator/getter/cleanup failures propagate and are not handled by coalescing.

These private C# member fragments use the earlier TryReadFirst/TryReadLast strategy. They model the bound property read, including a missing source receiver; their null handling is not a new public helper-function guard:

private static T? ReadValueBoundary<T>(IEnumerable<T>? source, bool last) where T : struct
{
    if (source is null) return null;
    T item;
    bool found = last ? TryReadLast(source, out item) : TryReadFirst(source, out item);
    return found ? item : null;
}
private static T? ReadReferenceBoundary<T>(IEnumerable<T?>? source, bool last) where T : class
{
    if (source is null) return null;
    T? item;
    bool found = last ? TryReadLast(source, out item) : TryReadFirst(source, out item);
    return found ? item : null;
}
private static T? ReadNullableBoundary<T>(IEnumerable<T?>? source, bool last) where T : struct
{
    if (source is null) return null;
    T? item;
    bool found = last ? TryReadLast(source, out item) : TryReadFirst(source, out item);
    return found ? item : null;
}

The constrained value result is genuine Nullable<T>. The reference result retains the selected reference; an acquired null payload and an empty sequence both produce ordinary absence. The nullable-element case returns its one existing nullable layer. Selecting the first null item does not skip forward to a later present item.

The private names are distinct on purpose. C# constraints and return type alone do not distinguish overload signatures. These fragments do not select public overloads, add DirectSharp constraint spellings or rewrite an imported IEnumerable<Integer> as IEnumerable<Nullable<Integer>>.

When the caller explicitly requires a result before returning a fixed T, a private strategy can check presence first:

private static T RequireBoundary<T>(IEnumerable<T>? source, bool last)
{
    if (source is null) throw new NullReferenceException();
    T item;
    bool found = last ? TryReadLast(source, out item) : TryReadFirst(source, out item);
    if (!found || item is null) throw new NullReferenceException();
    return item;
}

This illustrates the preceding ?? throw policy, not a public generic First contract. Empty input or a selected null payload throws; real zero/false/default structs return normally. A generic caller that must return absence still needs a representable declared contract and applicable constraints. It cannot silently change the CLR return of a fixed interface/override/imported method. Data-record generic lifting is a separate feature-specific rule, not permission to lift every generic method argument.

A native C# method returning unconstrained T? can still instantiate as int; Task<T?> can therefore instantiate as Task<int>. The native fixture verifies that assignment and its zero payload on empty input, alongside constrained nullable strategies. Inferred async alone cannot repair a result representation that loses absence.

Distinguish accessor reads from method calls

Empty parentheses are tolerated only when binding selects a readable non-indexed property after ordinary applicable calls have been considered. If an imported LINQ First()/Last() method is selected, its normal empty-source exception remains. Do not implement every call spelled First() as the absence-producing accessor, or force a helper ahead of ordinary binding. The property fallback rule and nullable declaration rules define those boundaries.

These strategies cover synchronous IEnumerable sources at known bound types. They do not select First/Last on IAsyncEnumerable, a blocking async bridge, public helper exports or IQueryable translation. Asynchronous iteration and fixed async ABI retain their existing contracts.

Strict and tolerant sequence selection

A C# iterator method defers its body. Immediate bounds checks therefore belong outside the returned iterator. This reference pattern validates source presence immediately and preserves the strict inclusive interval:

static IEnumerable<T> TakeInclusive<T>(IEnumerable<T> source, int start, int end)
{
    ArgumentNullException.ThrowIfNull(source);
    if (start < 0) throw new ArgumentOutOfRangeException(nameof(start));
    if (end < 0 || end < start) throw new ArgumentOutOfRangeException(nameof(end));
    return Enumerate();

    IEnumerable<T> Enumerate()
    {
        using var iterator = source.GetEnumerator();
        for (long position = 0; position <= end; position++)
        {
            if (!iterator.MoveNext())
                throw new ArgumentOutOfRangeException(nameof(end),
                    "The complete interval is unavailable.");
            if (position >= start) yield return iterator.Current;
        }
    }
}

For a seven-item source, TakeInclusive(source, 5, 10) can produce positions five and six, then throw when continued. Early consumer exit disposes the iterator without discovering an unread shortage. A wider loop position avoids overflow when the inclusive end is Integer.MaxValue. Each enumeration starts afresh; no source snapshot is implied.

Tolerant TryTake has a different execution contract. It cannot return a deferred non-null sequence now and later change the already-returned value into nothing when enumeration discovers no items. It collects the selected window once at the call:

static IReadOnlyList<T>? TryTakeInclusive<T>(IEnumerable<T>? source, int start, int end)
{
    if (source is null) return null;
    start = Math.Max(0, start);
    end = Math.Max(0, end);
    if (end < start) return null;

    using var iterator = source.GetEnumerator();
    List<T>? selected = null;
    for (long position = 0; position <= end && iterator.MoveNext(); position++)
    {
        if (position < start) continue;
        (selected ??= new List<T>()).Add(iterator.Current);
    }
    return selected;
}

This is the general enumerable path with the selected nullable IReadOnlyList result, not a final extension-container declaration. Known array/List metadata can optimize selection when equivalent. An enumerating Count prepass/restart is forbidden; arbitrary custom Count/indexer/enumerator behavior cannot be assumed interchangeable. A collected result retains object references, not deep copies.

Case Strict inclusive Take Tolerant inclusive TryTake
Nothing source Immediate ArgumentNullException, before bounds Nothing immediately, before normalization
Negative positions with present source Immediate ArgumentOutOfRangeException Normalize each to zero
End below start Immediate ArgumentOutOfRangeException Nothing after normalization, without traversal
Empty/start beyond end of source Deferred ArgumentOutOfRangeException Nothing at the call
Oversized end Yield available selected prefix, then fail if traversal continues Collect available selection and stop at exhaustion
Reuse result Fresh source traversal Reuse collected selection
Source reading/disposal fails Failure at traversal/cleanup Failure at call/cleanup, not a successful partial result

Count Take/Skip/TakeLast preserve strict requested-count checking, with valid strict zero and exact-length Skip cases. Optional count variants collect available selection at the call and return nothing if no values remain. General tail/remainder operations need exhaustion and storage. These are separate from imported LINQ contracts; the specification gives their individual C# patterns.

Acquire items without confusing them with completion

A reference loop over the accepted consumable interface reads presence from the result envelope:

static async Task DrainAsync<T>(DirectSharp.IConsumable<T> source,
    Func<T, Task> processAsync, CancellationToken cancellation)
{
    while (true)
    {
        DirectSharp.ConsumeResult<T> next = await source.AcquireAsync(cancellation);
        if (!next.HasItem) break;
        await processAsync(next.Item);
    }
}

This assumes ordinary System/Collections/Threading/Tasks imports across the snippets on this page and application-provided processing. A null item can be passed to processAsync when T permits it. The loop borrows its source; it supplies no implicit disposal, producer cancellation, acknowledgement or retry. The token is passed to acquisition, not inserted as a new hidden cancellation check before every body.

A custom concurrent consumable can declare IConcurrentConsumable<T> as its ordinary CLR capability interface. It promises acquisition/item-lifetime safety, not automatic thread safety of payload state. A completion-aware live wrapper that records producer failure closes admission, drains its buffered values, then rethrows the retained original failure on subsequent acquisitions instead of returning Completed. This requires distinct live, completed and faulted state: failed acquisition propagates the exception, while normal terminal completion yields Completed.

For channels, WaitToReadAsync followed by TryRead may need a retry if another consumer acquired the available item. For a completion-aware concurrent queue, arrival and completion must coordinate with the same wait state to avoid lost wake-ups. A bare empty probe cannot establish permanent completion.

For raw database readers, a Read/ReadAsync loop yields the same mutable current-record view. Project independent values before retaining them. Stop at the current result set, keep NextResult explicit and reject direct concurrent raw-reader consumption. A byte-chunk source needs independent storage and must preserve short positive reads; a blank text line is data. The adapter table describes these separate completion contracts.

Preserve helper culture and numeric defaults

Upper/Lower need a source-null guard before native invariant casing. UrlEncode needs a URI-component encoder, rather than form encoding or parsing a whole address. These private member fragments illustrate the selected strategies without choosing public containers:

private static string InvariantLower(string text)
{
    ArgumentNullException.ThrowIfNull(text);
    return text.ToLowerInvariant();
}

private static string EncodeComponent(string text)
{
    ArgumentNullException.ThrowIfNull(text);
    return Uri.EscapeDataString(text);
}

Native Upper uses the corresponding ToUpperInvariant strategy. Do not add strict scalar decoding to these casing methods; identifier-style case transforms have a separate strict segmentation profile. That profile preserves acronym/digit/combining-mark rules and requires its own implementation checks. Ordinary String comparison and current-culture interpolation are independent of these helper choices.

For a bound Decimal Round call with no mode, the reference operation is Math.Round(value, digits, MidpointRounding.AwayFromZero); use digits zero when omitted. Apply the corresponding Double overload for a bound Double call. A bare Math.Round(value) would silently restore its default ToEven behavior. Explicit mode, range validation, Truncate/Floor/Ceiling and Double special values follow the selected typed Math APIs. Do not force all inputs through Double or return Long from every integral-valued operation. The twelve member declarations leave container/import placement separate from the selected matrix.

HelperProfileChecks exercises native invariant casing under Turkish current culture, URI-component encoding, null guards, native typed midpoint/range/mode behavior and Double special values. The fixture does not implement public helper exports or identifier segmentation. The layout/escaping account below supplies the separately selected content profile; an arbitrary serializer/encoder can have different defaults.

Text layout and escaping strategies

The selected layout profile counts runtime StringInfo text elements. Validate the full source and supplied suffix before returning, then slice only at recognized element boundaries. These private C# member fragments assume ordinary System, System.Buffers, System.Globalization and System.Text imports. They use int counters, matching the selected Integer layout inputs in DirectSharp.Text.TextExtensions; these private fragments are reference strategies, not public library implementations:

private static void ValidateUtf16(string text, string parameter)
{
    for (int offset = 0; offset < text.Length;)
    {
        if (Rune.DecodeFromUtf16(text.AsSpan(offset), out _, out int consumed) != OperationStatus.Done)
            throw new ArgumentException("Malformed UTF-16.", parameter);
        offset += consumed;
    }
}

private static string Prefix(string text, int[] starts, int count) =>
    count == starts.Length ? text : text[..starts[count]];

private static string TruncateText(string source, int length, string suffix)
{
    ArgumentNullException.ThrowIfNull(source);
    if (length < 0) throw new ArgumentOutOfRangeException(nameof(length));
    ArgumentNullException.ThrowIfNull(suffix);
    ValidateUtf16(source, nameof(source));
    ValidateUtf16(suffix, nameof(suffix));
    var sourceStarts = StringInfo.ParseCombiningCharacters(source);
    var suffixStarts = StringInfo.ParseCombiningCharacters(suffix);
    if (sourceStarts.Length <= length) return source;
    int suffixCount = Math.Min(length, suffixStarts.Length);
    return Prefix(source, sourceStarts, length - suffixCount)
        + Prefix(suffix, suffixStarts, suffixCount);
}

Validation order matters: source null, numeric bound, suffix null, then complete UTF-16 validation before any successful fast return. A zero budget or already-fitting source does not authorize skipping validation of a supplied suffix. Prefix uses boundaries from the original String, preserving decomposed text and valid supplementary pairs without normalization. The suffix is budgeted before selecting a source prefix; an over-budget suffix is itself clipped. Allocations/segmentation can be optimized only while preserving these observations.

Wrap needs a separate word-packing loop:

  1. Validate source/positive width and the complete UTF-16 input.
  2. Scan existing CRLF/CR/LF boundaries, retaining each original delimiter exactly.
  3. In each line, split only at ASCII space/tab and omit empty words.
  4. Segment each word into text elements. Greedily place words with one separating space; emit a platform newline when the next word does not fit.
  5. Split oversized words into width-bounded pieces at element boundaries. Full pieces occupy their own line; a final short piece can share its line with following words.
  6. Preserve empty hard lines and a final original delimiter. Do not add a new final delimiter merely because a word exactly fits.

The complete isolated patterns show the loop, including overflow-safe size arithmetic. Native String.Length/substrings alone would count code units and could split a recognized element. A generic whitespace split would also change the selected treatment of NBSP, and normalizing all line endings would lose original CRLF/CR/LF boundaries.

For the shared JSON/ordinary-C# contents profile, strict validation followed by code-unit output preserves every valid supplementary pair while applying the selected canonical escapes:

private static string EscapeContents(string source)
{
    ArgumentNullException.ThrowIfNull(source);
    ValidateUtf16(source, nameof(source));
    var result = new StringBuilder();
    foreach (char unit in source)
    {
        switch (unit)
        {
            case '"': result.Append("\\\""); break;
            case '\\': result.Append("\\\\"); break;
            case '\b': result.Append("\\b"); break;
            case '\f': result.Append("\\f"); break;
            case '\n': result.Append("\\n"); break;
            case '\r': result.Append("\\r"); break;
            case '\t': result.Append("\\t"); break;
            default:
                if (unit < 0x20 || unit is >= '\u007F' and <= '\u009F' or '\u2028' or '\u2029')
                    result.Append("\\u").Append(((int)unit).ToString("X4", CultureInfo.InvariantCulture));
                else
                    result.Append(unit);
                break;
        }
    }
    return result.ToString();
}

Do not replace this with a serializer whose delimiter, malformed-input, non-ASCII or HTML-encoding defaults differ. The emitted contents omit outer quotes; they can reconstruct the original valid String in the two specified double-quoted contexts. They are not HTML script content or another C# literal form.

Validate Unicode before narrowing

The scalar constructor accepts Long and validates the complete input before passing an Integer to Rune:

static string FromCodePoint(long value)
{
    if (value < 0 || value > 0x10FFFF || value is >= 0xD800 and <= 0xDFFF)
        throw new ArgumentOutOfRangeException(nameof(value));
    return new System.Text.Rune((int)value).ToString();
}

Narrowing first could wrap a large invalid Long into a valid scalar. Code-unit construction differs: it accepts every value from zero through 65535, including isolated surrogate units. CodePoint must decode exactly one scalar from the entire String, and CodePoints must reject malformed UTF-16 when reached rather than silently substitute replacement text. The deferred view validates null immediately and creates fresh traversal state each time. Ordinary String storage and Char iteration remain UTF-16.

A generic C# helper can exchange addressable storage of the same T without requiring a native Interlocked overload. Properties/indexers instead need captured receivers/index arguments and synchronous accessor callbacks. One illustrative accessor helper is:

static void Exchange<T>(Func<T> readLeft, Action<T> writeLeft,
    Func<T> readRight, Action<T> writeRight, object domain)
{
    lock (domain)
    {
        T left = readLeft();
        T right = readRight();
        writeLeft(right);
        writeRight(left);
    }
}

The domain is a backend coordination object shared with related atomic regions, not a new source lock keyword or a fresh object created per call. Capture location expressions once, in source order, before invoking this pattern. A getter failure causes no exchange writes. A setter failure can leave partial changes; lock release is guaranteed, rollback is not. Aliasing and captured mutable structs must preserve the original storage.

Ordinary swap in a concurrent body uses the same protected semantics. That exception does not make unrelated captured mutations safe or coordinate arbitrary external CLR access automatically. The compiler still has to choose stable domains, diagnose invalid writable targets and preserve lexical concurrency intent. See exchange rules.

Inline branches lower to ordinary async callables

An inline run body can lower to a generated local async function or an async delegate. The surrounding coordinator registers and starts that callable as one owned producer. Its return statements are local to the callable, so ordinary C# state-machine and finally/await-using behavior express the branch's sequential steps and cleanup.

For example, the two inline download/length branches in the concurrency reference have these callable bodies:

async Task<int> InvoiceBranchAsync(CancellationToken producerToken)
{
    string text = await client.GetStringAsync(invoiceAddress, producerToken);
    return text.Trim().Length;
}

async Task<int> ContractBranchAsync(CancellationToken producerToken)
{
    string text = await client.GetStringAsync(contractAddress, producerToken);
    return text.Trim().Length;
}

The excerpt assumes ordinary threading/task imports and supplied client/address variables. Once each branch is admitted by its owning scope, invoke it with that producer's effective token and retain the returned Task<int>. Invoke independently admitted branches without awaiting the first before starting the second. Async method invocation captures body failures in its task even when the body fails before suspending, allowing the coordinator to retain that producer outcome and settle other owned work. No implicit Task.Run is needed. CPU-heavy synchronous prefixes do not become parallel merely because the generated method is async.

The coordinator must still enforce limits, own nested work, join every admitted producer, apply the all/first/any outcome rules below, and only then publish logical results. A return expression can finish before async cleanup; that is not branch success until cleanup completes. Nested ownership may need a generated try/finally settlement region in addition to the local function. An early branch return must not bypass it or release capacity early. A resultless branch uses a Task-returning callable. Synchronous-only branches may use an equivalent completed/faulted operation without changing the observable contract. These are private lowering choices, not new public standard-library types.

Task capture has no such coordinator: a direct task_of call remains an ordinary invocation returning its native awaitable. Forgotten-operation diagnostics require DirectSharp flow analysis; they are not supplied by the generated local function or by .NET garbage collection. A backend must preserve the default continuation behavior of authored awaits and surrounding code resumed after generated cleanup/joins, using an explicitly configured awaiter only where that configuration is requested.

The isolated C# reference checks exercise independently progressing branches, delayed cleanup before publication, branch-local return, source-ordered multiple failures after joins, and Task.Run exception observation. They validate native lowering patterns, not parsing, warning emission or a production scope coordinator.

Structured concurrency needs an outcome model

Task.WhenAll is useful for joining owned work, but awaiting it does not supply the entire DirectSharp failure policy. The backend must retain producer identity, actual task state, source order, selected outcome, cancellation attribution and the recorded external cause through publication.

Case Required result after owned settlement
first: failure followed by success Select the success; cooperatively stop unfinished losers where supported
any: selected failure followed by success Propagate the selected original failure
Successful first/any with losing faults Observe losing outcomes without destroying the selected success, subject to recorded external causes
all failure / first with no success One original failure or source-ordered AggregateException for several
Cancellation request/callback throws Observe/suppress request errors and continue joining; do not include them as producer failures
Producer ignores cancellation Wait for its natural settlement; do not abandon it or claim thread termination
External timeout/caller cause before publication Can prevent selected success, including during a join; first recorded cause retained
Otherwise-propagated genuine producer failure plus external cause Preserve producer failure priority
No first/any producers Diagnose statically; runtime zero-producer paths throw InvalidOperationException
Related values from competing producers Publish one ordinary result object; never mix members selected from separate winners

A successful selection and successful publication are different moments. Cancellation request failure must not skip joins. An explicit token override remains explicit; an imported call without a compatible cancellable contract cannot be forced to stop. any does not cancel merely on selection. break in a concurrent loop stops scheduling and joins without automatically cancelling iterations.

Concurrent collection publication preserves source order even when iteration completion differs. A limit bounds a whole iteration, including its owned nested operations; conditions run sequentially in the coordinator after capacity is available. Gate acquisition has its own atomic grant/cause boundary and no extra post-grant cancellation check. Concurrency rules define these details independently of private helper design.

Named loop transfers and marks

Named loops use with name: identifier; break identifier and continue identifier select an enclosing loop. Source marks use mark identifier, and goto identifier can jump forward or backward. The developer bridge shows a C# label-based implementation of nested named-loop transfers. A continue destination must preserve the target's increment/acquisition/condition protocol, including the trailing test of post-test repeat.

Generated labels are an implementation technique, while source marks are language destinations. Both require deliberate scope, definite-assignment, cleanup and ownership analysis. A direct textual C# goto is insufficient evidence that a transfer is valid DirectSharp. Concurrent breaks must request scheduling termination and settle admitted work at the owning boundary; joining the current worker from itself would deadlock. Named transfers and goto do not authorize cross-callable or extra concurrent-boundary exits. See chapter 7.

What verification establishes

Reference checks should exercise observables: side-effect counts, exception identity, prefix/failure timing, task settlement, resource cleanup and retained values. A code sample that happens to compile is insufficient evidence for source semantics.