簡體   English   中英

使用CodeDOM生成字段而不是屬性

[英]Generate fields instead of properties with CodeDOM

我使用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創建一個具有相同名稱的新屬性, 如此答案所示。 因此,我不需要搜索代碼來查找私有后備字段的發生,而可以通過調用該屬性來替換它們。

不,沒有選項可以設置為允許此操作,因為如果您的屬性是字段或屬性(假設我們不使用反射)並且使用公共字段被認為是不好的做法,那么使用代碼就無關緊要。

無論如何,我找到了一種方法來實現此目的,方法是將該屬性的所有注釋和屬性復制到私有后備字段,並使該字段公開。 但是請記住,這樣做主要是一個糟糕的設計思想。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM