0

I created some code from an XSD-schema-file using CodeDOM:

XmlSchemaImporter importer = new XmlSchemaImporter(schemas);
CodeNamespace code = new CodeNamespace(targetNamespace);
XmlCodeExporter exporter = new XmlCodeExporter(code);

foreach (XmlSchemaElement element in schema.Elements.Values)
{
    XmlTypeMapping mapping = importer.ImportTypeMapping(element.QualifiedName);
    exporter.ExportTypeMapping(mapping);
}

Now within my post-processing I realized that this code will generate properties like this:

bool prop1Field;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public bool Prop1
{
    get
    {
        return prop1Field;
    }
    set
    {
        prop1Field = value;
    }
}

But I want the generator to simply produce fields instead. Is there a way to achieve this? I know xsd.exe also produces fields when using the /f-argument.

EDIT: Afterwards I want to replace those by auto-properties. To do so with the current approach I´d have to delete the backing-field from the property and all its occurences within the generated code. If CodeDOM however generates a public field in the first place all I had to do is to delete this field, create a new property with the same name using CodeSnippedTypeMember as shown in this answer. Thus I won´t need to search the codes for occurences of the private backing-field and replace them by calls to the property.

Community
  • 1
  • 1
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111

1 Answers1

0

No, there´s no option to be set to allow this as it shouldn´t matter for consuming code if your attribute is a field or a property (assuming we don´t use reflection) and public fields are considered bad practice.

Anyway I found a way to achieve this by copying all the comments and attributes of the property to the private backing-field and make the field public. However remember that doing so is mostly a bad design-idea.

    public void Process(CodeNamespace code, XmlSchema schema)
    {
        foreach (var type in code.Types.Cast<CodeTypeDeclaration>().Where(x => !x.IsEnum))
        {
            var result = new List<CodeMemberField>();
            var properties = type.Members.OfType<CodeMemberProperty>().ToList();
            foreach (var property in properties)
            {
                ReplacePropertyByField(type, property);
            }
        }
    }


    private static void ReplacePropertyByField(CodeTypeDeclaration type, CodeMemberProperty property)
    {
        var backingField = GetBackingField(property, type);
        backingField.Comments.AddRange(property.Comments);
        backingField.Attributes = property.Attributes;
        backingField.CustomAttributes = property.CustomAttributes;
        backingField.Name = property.Name;
        type.Members.Remove(property);
    }

    private static CodeMemberField GetBackingField(CodeMemberProperty property, CodeTypeDeclaration type)
    {
        var getterExpression = ((CodeMethodReturnStatement)property.GetStatements[0]).Expression;
        var backingFieldName = ((CodeFieldReferenceExpression)getterExpression).FieldName;
        return type.Members.OfType<CodeMemberField>().Single(x => x.Name == backingFieldName);
    }
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111