Repository navigation
feat: add ToProperty, ObservableAsPropertyHelper and [ObservableAsProperty] - #119
Merged
Merged
Conversation
…perty] Back a read-only property with the latest value of an observable, through generated code that allocates nothing per value and adds no types to the consumer's assembly. Runtime - ObservableAsPropertyHelper<T>: private core, serialized delivery, a distinct gate seeded with the initial value, ThrownExceptions, deferred subscription and Default. The gate is an int taken with one compare-exchange and a SpinWait backoff that never sleeps on .NET Core. - ToProperty overloads for a selector or a property name, with an initial value or factory, deferred subscription, a scheduler, and an out helper. Selectors are Func, string names dispatch by value, and initial-value overloads carry OverloadResolutionPriority. - ToPropertyUnsafe: the reflection fallback, which finds the raise member at run time and binds it once per helper. - [ObservableAsProperty] for partial get-only properties. Generator and analyzer - ToProperty pipeline with raise plugins (a raise method, or an accessor added to a partial type) and a syntax-first extractor. - [ObservableAsProperty] generator via ForAttributeWithMetadataName. - File-and-line dispatch now matches Windows paths and the member-name line of chained calls. - RXUIBIND012, RXUIBIND013 and RXUIBIND014. Benchmarks and examples - ToProperty, contention, ToPropertyUnsafe, extraction and discovery benchmarks; benchmarks are configured by config only, with a net462 job on Windows. - Documentation examples and platform verifiers for net462-net11.0, WPF, WinForms and MAUI; System.Reactive examples removed.
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #119 +/- ##
==========================================
- Coverage 98.05% 97.05% -1.00%
==========================================
Files 349 368 +19
Lines 12731 13876 +1145
Branches 1539 1774 +235
==========================================
+ Hits 12483 13468 +985
- Misses 248 408 +160 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
Adds
ToProperty, which backs a read-only property with the latest value of an observable. The generator writes the code that raises the property's change notification, so each new value allocates nothing and no types are added to the consumer's assembly.ObservableAsPropertyHelper<T>holds the latest value and raises the notification for each new one, in order, on the producing thread or a given scheduler. It supports deferred subscription, an initial value or factory,ThrownExceptions, andDefaultfor a property that never changes.ToPropertyoverloads take the property as a selector or a constant name, with an initial value or factory, deferred subscription, a scheduler, and anoutparameter for the helper.partialtype that invokes its own event.[ObservableAsProperty]on a partial get-only property generates the property body and its helper field.ToPropertyUnsafeis the reflection fallback for a call the generator cannot read, such as a name held in a variable. It carries trimming and dynamic-code annotations.Why
Projects using this generator could not add another source generator to back properties with observables, so they had no way to do it with bindings. Running the new verifiers on .NET Framework on Windows also showed that pre-C# 10 dispatch never matched a Windows path or a multi-line chained call, so those calls threw at run time.
Breaking changes
None.
How this was verified
Tests cover the helper, the generator, the analyzers and the reflection fallback. The platform verifiers ran on Linux and on a Windows machine, for .NET Framework 4.6.2 through .NET 11, WPF, WinForms and MAUI. Apple platforms could not be run here.
Notes for the reviewer
ObservableAsPropertyHelper.cs, then the ToProperty extractor and code generator. The subtle parts are the helper's gate and serialized delivery, and the dispatch rules for string names andOverloadResolutionPriority.RuntimePropertyRaisersuppresses SES1406 on its two lookups that must reach non-public members; this was agreed as the one allowed use.ToPropertyandToPropertyUnsafestub files, the PublicAPI baselines, the verified snapshots, and the removal of attributes from the benchmark classes.Checklist