【问题标题】:Generate fields instead of properties with CodeDOM使用 CodeDOM 生成字段而不是属性
【发布时间】:2016-09-05 19:34:47
【问题描述】:

我使用 CodeDOM 从 XSD 模式文件创建了一些代码:

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);
}

现在在我的后期处理中,我意识到这段代码将生成如下属性:

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

但我希望生成器只生成字段。有没有办法做到这一点?我知道xsd.exe 在使用/f-argument 时也会产生字段。

编辑:之后我想用自动属性替换那些。要使用当前方法执行此操作,我必须从属性中删除支持字段及其在生成的代码中的所有出现。然而,如果 CodeDOM 首先生成了一个public 字段,我所要做的就是删除该字段,然后使用CodeSnippedTypeMember 创建一个同名的新属性,如this answer 所示。因此,我不需要搜索私有支持字段出现的代码并通过调用属性来替换它们。

【问题讨论】:

    标签: c# xsd codedom


    【解决方案1】:

    不,没有选项可以设置为允许这样做,因为如果您的属性是字段或属性(假设我们不使用反射)并且公共字段被认为是不好的做法,那么使用代码应该无关紧要.

    无论如何,我找到了一种方法来实现这一点,方法是将属性的所有 cmets 和属性复制到私有支持字段并公开该字段。但是请记住,这样做大多是一个糟糕的设计理念。

        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);
        }
    

    【讨论】:

      猜你喜欢
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 2011-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多