RSCG – PropertyChangedSourceGenerator
RSCG – PropertyChangedSourceGenerator
name | PropertyChangedSourceGenerator |
nuget | https://www.nuget.org/packages/PropertyChanged.SourceGenerator/ |
link | https://github.com/canton7/PropertyChanged.SourceGenerator |
author | Antony Male |
Generating PropertyChange to properties
This is how you can use PropertyChangedSourceGenerator .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.8"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> <PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> </PropertyGroup> </Project>
The code that you will use is
using PropChangeDemo; Person person = new (); person.FirstName = "Andrei"; Console.WriteLine (person.FirstName);
using PropertyChanged.SourceGenerator; namespace PropChangeDemo; partial class Person { [Notify] private string? _FirstName; }
The code that is generated is
// <auto-generated> // Auto-generated by PropertyChanged.SourceGenerator 1.0.8.0 // </auto-generated> namespace PropertyChanged.SourceGenerator { /// <summary> /// Specifies the accessibility of a generated property getter /// </summary> internal enum Getter { Public = 6, ProtectedInternal = 5, Internal = 4, Protected = 3, PrivateProtected = 2, Private = 1, } /// <summary> /// Specifies the accessibility of a generated property getter /// </summary> internal enum Setter { Public = 6, ProtectedInternal = 5, Internal = 4, Protected = 3, PrivateProtected = 2, Private = 1, } /// <summary> /// Instruct PropertyChanged.SourceGenerator to generate a property which implements INPC using this backing field /// </summary> [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false)] [global::System.Diagnostics.Conditional("DEBUG")] internal class NotifyAttribute : global::System.Attribute { /// <summary> /// Generate a property whose name is derived from the name of this field, with a public getter and setter /// </summary> public NotifyAttribute() { } /// <summary> /// Generate a property with the given name, and optionally the given getter and setter accessibilities /// </summary> /// <param name="name">Name of the generated property</param> /// <param name="get">Accessibility of the generated getter</param> /// <param name="set">Accessibility of the generated setter</param> public NotifyAttribute(string name, Getter get = Getter.Public, Setter set = Setter.Public) { } /// <summary> /// Generate a property whose name is derived from the name of this field, with the given getter and optionally setter accessibilities /// </summary> /// <param name="get">Accessibility of the generated getter</param> /// <param name="set">Accessibility of the generated setter</param> public NotifyAttribute(Getter get, Setter set = Setter.Public) { } /// <summary> /// Generate a property whose name is derived from the name of this field, with a public getter and the given setter accessibility /// </summary> /// <param name="set">Accessibility of the generated setter</param> public NotifyAttribute(Setter set) { } /// <summary> /// If <c>true</c>, the generated property will be <c>virtual</c>. /// </summary> public bool IsVirtual { get; set; } } /// <summary> /// Instruct PropertyChanged.SourceGenerator to also raise INPC notifications for the named properties whenever the property this is applied to changes /// </summary> [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = true)] [global::System.Diagnostics.Conditional("DEBUG")] internal class AlsoNotifyAttribute : global::System.Attribute { /// <summary> /// Raise INPC notifications for the given properties when the property generated for this backing field changes /// </summary> /// <param name="otherProperties">Other properties to raise INPC notifications for</param> public AlsoNotifyAttribute(params string[] otherProperties) { } } /// <summary> /// Instruct PropertyChanged.SourceGenerator to raise INPC notifications for this property whenever one of the named generated properties is changed /// </summary> [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false)] [global::System.Diagnostics.Conditional("DEBUG")] internal class DependsOnAttribute : global::System.Attribute { /// <summary> /// Raise an INPC notification for this property whenever one of the named properties is changed /// </summary> /// <param name="dependsOn">Other properties this property depends on</param> public DependsOnAttribute(params string[] dependsOn) { } } /// <summary> /// Instruct PropertyChanged.SourceGenerator to assign true to this boolean property whenver any generated member changes /// </summary> [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = true)] [global::System.Diagnostics.Conditional("DEBUG")] internal class IsChangedAttribute : global::System.Attribute { } /// <summary> /// Specifies an attribute which will be added to the generated property for this backing field /// </summary> /// <remarks> /// The string passed to this attribute will be placed verbatim into the generated code. All types must therefore by fully-qualified. /// </remarks> [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = true)] [global::System.Diagnostics.Conditional("DEBUG")] internal class PropertyAttributeAttribute : global::System.Attribute { /// <summary> /// Specify an attribute which iwll be added to the generated property for this backing field /// </summary> /// <param name="attribute">An attribute to place on the generated property</param> public PropertyAttributeAttribute(string attribute) { } } }
// <auto-generated> // Auto-generated by PropertyChanged.SourceGenerator 1.0.8.0 // </auto-generated> namespace PropertyChanged.SourceGenerator.Internal { internal static class EventArgsCache { private static global::System.ComponentModel.PropertyChangedEventArgs _PropertyChanged_FirstName; public static global::System.ComponentModel.PropertyChangedEventArgs PropertyChanged_FirstName => _PropertyChanged_FirstName ??= new global::System.ComponentModel.PropertyChangedEventArgs(@"FirstName"); } }
// <auto-generated> // Auto-generated by PropertyChanged.SourceGenerator 1.0.8.0 // </auto-generated> #nullable enable namespace PropChangeDemo { partial class Person : global::System.ComponentModel.INotifyPropertyChanged { /// <inheritdoc /> public event global::System.ComponentModel.PropertyChangedEventHandler? PropertyChanged; public string? FirstName { get => this._FirstName; set { if (!global::System.Collections.Generic.EqualityComparer<string?>.Default.Equals(value, this._FirstName)) { this._FirstName = value; this.OnPropertyChanged(global::PropertyChanged.SourceGenerator.Internal.EventArgsCache.PropertyChanged_FirstName); } } } /// <summary> /// Raises the PropertyChanged event /// </summary> /// <param name="eventArgs">The EventArgs to use to raise the event</param> protected virtual void OnPropertyChanged(global::System.ComponentModel.PropertyChangedEventArgs eventArgs) { this.PropertyChanged?.Invoke(this, eventArgs); } } }
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyChangedSourceGenerator
Leave a Reply