diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs index bf4d8e90..6382e47f 100644 --- a/XmlSchemaClassGenerator.Tests/XmlTests.cs +++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices.ComTypes; using System.Text; using System.Text.RegularExpressions; using System.Xml; @@ -220,6 +221,72 @@ public void TestListWithPublicPropertySettersWithoutConstructors() Assert.Null(collectionPropertyInfo.GetValue(myClassInstance)); } } + + [Fact] + public void TestListWithPublicPropertySettersWithoutConstructorsSpecified() + { + var assembly = Compiler.Generate("ListPublicWithoutConstructorInitialization", ListPattern, new Generator + { + GenerateNullables = true, + IntegerDataType = typeof(int), + DataAnnotationMode = DataAnnotationMode.All, + GenerateDesignerCategoryAttribute = false, + GenerateComplexTypesForCollections = true, + EntityFramework = false, + GenerateInterfaces = true, + NamespacePrefix = "List", + GenerateDescriptionAttribute = true, + TextValuePropertyName = "Value", + CollectionSettersMode = CollectionSettersMode.PublicWithoutConstructorInitialization + }); + Assert.NotNull(assembly); + var myClassType = assembly.GetType("List.MyClass"); + Assert.NotNull(myClassType); + var iListType = typeof(Collection<>); + var collectionPropertyInfos = myClassType.GetProperties().Where(p => p.PropertyType.IsGenericType && iListType.IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition())).OrderBy(p => p.Name).ToList(); + var publicCollectionPropertyInfos = collectionPropertyInfos.Where(p => p.SetMethod.IsPublic).OrderBy(p => p.Name).ToList(); + Assert.True(collectionPropertyInfos.Count > 0); + Assert.Equal(collectionPropertyInfos, publicCollectionPropertyInfos); + var myClassInstance = Activator.CreateInstance(myClassType); + + var propertyNamesWithSpecifiedPostfix = publicCollectionPropertyInfos.Select(p => p.Name + "Specified").ToHashSet(); + var propertiesWithSpecifiedPostfix = + myClassType.GetProperties().Where(p => propertyNamesWithSpecifiedPostfix.Contains(p.Name)).ToList(); + + //Null collection + foreach (var propertyInfo in propertiesWithSpecifiedPostfix) + { + Assert.False((bool)propertyInfo.GetValue(myClassInstance)); + } + + foreach (var propertyInfo in publicCollectionPropertyInfos) + { + var collection = Activator.CreateInstance(propertyInfo.PropertyType); + propertyInfo.SetValue(myClassInstance, collection); + } + + //Not Null but empty collection + foreach (var propertyInfo in propertiesWithSpecifiedPostfix) + { + Assert.False((bool)propertyInfo.GetValue(myClassInstance)); + } + + foreach (var propertyInfo in publicCollectionPropertyInfos) + { + + var collection = Activator.CreateInstance(propertyInfo.PropertyType); + propertyInfo.PropertyType.InvokeMember("Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collection, + new object[] {null}); + propertyInfo.SetValue(myClassInstance, collection); + } + + //Not Null and not empty collection + foreach (var propertyInfo in propertiesWithSpecifiedPostfix) + { + Assert.True((bool)propertyInfo.GetValue(myClassInstance)); + } + } + [Fact, TestPriority(1)] [UseCulture("en-US")] diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index 539673c2..4dcba29c 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -1058,6 +1058,11 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi var listReference = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), Name); var countReference = new CodePropertyReferenceExpression(listReference, "Count"); var notZeroExpression = new CodeBinaryOperatorExpression(countReference, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(0)); + if (Configuration.CollectionSettersMode == CollectionSettersMode.PublicWithoutConstructorInitialization) + { + var notNullExpression = new CodeBinaryOperatorExpression(listReference, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); + notZeroExpression = new CodeBinaryOperatorExpression(notNullExpression, CodeBinaryOperatorType.BooleanAnd, notZeroExpression); + } var returnStatement = new CodeMethodReturnStatement(notZeroExpression); specifiedProperty.GetStatements.Add(returnStatement);