From ecc680552a27b1b99e3065e61a3203ddc47c3c10 Mon Sep 17 00:00:00 2001 From: Guilherme Bufolo Date: Fri, 8 Mar 2019 15:19:57 +0100 Subject: [PATCH 1/4] Create a thread safe OnPropertyChanged event method. --- XmlSchemaClassGenerator/TypeModel.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index ad6247d1..5af2e89a 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -300,14 +300,20 @@ public override CodeTypeDeclaration Generate() }; var param = new CodeParameterDeclarationExpression(typeof(string), "propertyName"); onPropChangedMethod.Parameters.Add(param); + var propChangedVar = new CodeVariableDeclarationStatement("var", "propChanged") + { + InitExpression = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "PropertyChanged") + }; + onPropChangedMethod.Statements.Add(propChangedVar); + onPropChangedMethod.Statements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( - new CodeEventReferenceExpression(null, "PropertyChanged"), + new CodeVariableReferenceExpression(propChangedVar.Name), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeExpressionStatement(new CodeDelegateInvokeExpression( - new CodeEventReferenceExpression(null, "PropertyChanged"), + new CodeVariableReferenceExpression(propChangedVar.Name), new CodeThisReferenceExpression(), new CodeObjectCreateExpression( "PropertyChangedEventArgs", From bf75cab044158b02cf635f810e8590409380a5c3 Mon Sep 17 00:00:00 2001 From: Guilherme Bufolo Date: Fri, 8 Mar 2019 15:35:57 +0100 Subject: [PATCH 2/4] OnPropertyChanged with nameof instead of string Prefer `OnPropertyChanged(nameof())` instead of OnPropertyChanged("") because the first one is more friendly towards tools. --- XmlSchemaClassGenerator/TypeModel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index 5af2e89a..0585f494 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -548,7 +548,7 @@ internal static string GetAccessors(string memberName, string backingFieldName, if (!{0}.Equals(value)) {{ {0} = value; - OnPropertyChanged(""{1}""); + OnPropertyChanged(nameof({1})); }} }} }}", backingFieldName, memberName, (privateSetter ? "private " : string.Empty))); @@ -566,7 +566,7 @@ internal static string GetAccessors(string memberName, string backingFieldName, if ({0} == null || value == null || !{0}.Equals(value)) {{ {0} = value; - OnPropertyChanged(""{1}""); + OnPropertyChanged(nameof({1})); }} }} }}", backingFieldName, memberName, (privateSetter ? "private " : string.Empty))); @@ -584,7 +584,7 @@ internal static string GetAccessors(string memberName, string backingFieldName, if ({0} == null || value == null || !{0}.SequenceEqual(value)) {{ {0} = value; - OnPropertyChanged(""{1}""); + OnPropertyChanged(nameof({1})); }} }} }}", backingFieldName, memberName, (privateSetter ? "private " : string.Empty))); From 2151bac2be58faf140f3de30e66bec5569d55892 Mon Sep 17 00:00:00 2001 From: Guilherme Bufolo Date: Fri, 8 Mar 2019 15:36:32 +0100 Subject: [PATCH 3/4] Fixed whitespaces and added DebuggerDisplay to TypeModel and PropretyModel. --- XmlSchemaClassGenerator/TypeModel.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index 0585f494..b9c4712f 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -108,6 +108,7 @@ private static DocumentationModel GetSingleDoc(IEnumerable d } } + [DebuggerDisplay("{Name}")] public abstract class TypeModel { protected static readonly CodeDomProvider CSharpProvider = CodeDomProvider.CreateProvider("CSharp"); @@ -501,6 +502,7 @@ public override CodeExpression GetDefaultValueFor(string defaultString, bool att } } + [DebuggerDisplay("{Name}")] public class PropertyModel { public TypeModel OwningType { get; set; } @@ -1281,15 +1283,15 @@ public override CodeExpression GetDefaultValueFor(string defaultString, bool att var rv = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(DateTime)), "Parse", new CodePrimitiveExpression(defaultString)); return rv; } - else if (type == typeof(bool) && !string.IsNullOrWhiteSpace(defaultString)) + else if (type == typeof(bool) && !string.IsNullOrWhiteSpace(defaultString)) { - if (defaultString == "0") - return new CodePrimitiveExpression(false); + if (defaultString == "0") + return new CodePrimitiveExpression(false); else if (defaultString == "1") - return new CodePrimitiveExpression(true); + return new CodePrimitiveExpression(true); else - return new CodePrimitiveExpression(Convert.ChangeType(defaultString, ValueType)); - } + return new CodePrimitiveExpression(Convert.ChangeType(defaultString, ValueType)); + } return new CodePrimitiveExpression(Convert.ChangeType(defaultString, ValueType, CultureInfo.InvariantCulture)); } From 3353721a7452d8011af336933bf8c6b874354c7f Mon Sep 17 00:00:00 2001 From: Guilherme Bufolo Date: Mon, 11 Mar 2019 09:45:49 +0100 Subject: [PATCH 4/4] Using ?. instead of if ( = null) check. --- XmlSchemaClassGenerator/TypeModel.cs | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index b9c4712f..fd0bde7c 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -287,12 +287,13 @@ public override CodeTypeDeclaration Generate() if (Configuration.EnableDataBinding) { - classDeclaration.Members.Add(new CodeMemberEvent() + var propertyChangedEvent = new CodeMemberEvent() { Name = "PropertyChanged", Type = new CodeTypeReference(typeof(PropertyChangedEventHandler), Configuration.CodeTypeReferenceOptions), Attributes = MemberAttributes.Public, - }); + }; + classDeclaration.Members.Add(propertyChangedEvent); var onPropChangedMethod = new CodeMemberMethod { @@ -301,25 +302,9 @@ public override CodeTypeDeclaration Generate() }; var param = new CodeParameterDeclarationExpression(typeof(string), "propertyName"); onPropChangedMethod.Parameters.Add(param); - var propChangedVar = new CodeVariableDeclarationStatement("var", "propChanged") - { - InitExpression = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "PropertyChanged") - }; - onPropChangedMethod.Statements.Add(propChangedVar); - - onPropChangedMethod.Statements.Add( - new CodeConditionStatement( - new CodeBinaryOperatorExpression( - new CodeVariableReferenceExpression(propChangedVar.Name), - CodeBinaryOperatorType.IdentityInequality, - new CodePrimitiveExpression(null)), - new CodeExpressionStatement(new CodeDelegateInvokeExpression( - new CodeVariableReferenceExpression(propChangedVar.Name), - new CodeThisReferenceExpression(), - new CodeObjectCreateExpression( - "PropertyChangedEventArgs", - new CodeArgumentReferenceExpression("propertyName")) - )))); + var threadSafeDelegateInvokeExpression = new CodeSnippetExpression($"{propertyChangedEvent.Name}?.Invoke(this, new PropertyChangedEventArgs({param.Name}))"); + + onPropChangedMethod.Statements.Add(threadSafeDelegateInvokeExpression); classDeclaration.Members.Add(onPropChangedMethod); }