如何使用 Codedom 添加自动 属性

How to add auto property using Codedom

我正在尝试使用 codedom 生成自动 属性,但没有成功。我尝试了不同的解决方案,但每一个都导致了问题。我正在尝试生成如下内容

        [FindsBy(How = How.Id, Using = "AllTabs")]
        public IWebElement SaveButton { get; set; }

我能够毫无问题地创建属性,但无法创建自动 属性。

如果我尝试使用此处列出的解决方案 autoproperty

        CodeTypeDeclaration newType = new CodeTypeDeclaration("TestType");
        CodeSnippetTypeMember snippet = new CodeSnippetTypeMember();

        snippet.Comments.Add(new CodeCommentStatement("this is integer property", true));
        snippet.Text="public int IntergerProperty { get; set; }";

        newType.Members.Add(snippet);

然后我无法在 属性 上添加属性,它只是打印出没有属性的 属性。有什么方法可以生成自动 属性 并使用属性吗?

显然你没有理解你所指的答案。它将 文字文本 插入到源流中,因此以下内容应该适合您:

        var newType = new CodeTypeDeclaration("TestType");
        var snippet = new CodeSnippetTypeMember();

        snippet.Text = @"
[FindsBy(How = How.Id, Using = ""AllTabs"")]
public IWebElement SaveButton { get; set; }
";

        newType.Members.Add(snippet);

请注意,CodeSnippetTypeMember 完全忽略了 CodeDom 提供的验证,因此使用此机制很容易生成非编译代码。 Roslyn does support auto-properties natively when in a C# context.

正如链接问题的公认答案所述,CodeDom 不支持自动属性的原因是它们是所有 .NET 语言中都不存在的语法糖,而 CodeDom 旨在作为语言-尽可能不可知。因此,CodeDom 无法了解或支持 auto-属性.

的概念

为了避免使用在实际编译之前未发现错误风险的片段,您可以使用一种方法自动创建带有支持字段的属性(这是编译器在内部使用自动 属性无论如何):

private static CodeMemberProperty makeAutoProperty(CodeTypeDeclaration containingClass, CodeTypeReference propertyType, string propertyName )
        {
            CodeMemberField backingField = new CodeMemberField();
            backingField.Name = propertyName + "_";
            backingField.Type = propertyType;
            CodeVariableReferenceExpression backingFieldRef = new CodeVariableReferenceExpression(backingField.Name);
            containingClass.Members.Add(backingField);

            CodeMemberProperty property = new CodeMemberProperty();
            property.Name = propertyName;
            property.Type = propertyType;
            property.HasGet = true;
            property.HasSet = true;
            property.GetStatements.Add(new CodeMethodReturnStatement(backingFieldRef));
            property.SetStatements.Add(new CodeAssignStatement(backingFieldRef, new CodeVariableReferenceExpression("value")));
            containingClass.Members.Add(property);

            return property;
        }

这使得添加与自动添加一样容易属性。您可以使用这样的方法:

            // Make the property
            CodeMemberProperty saveButtonField = makeAutoProperty(_class, new CodeTypeReference("IWebElement"), "saveButton");
            // Modify the access
            saveButtonField.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            // Add the attribute decorator
            var attr = new CodeAttributeDeclaration(new CodeTypeReference("FindsBy"));
            saveButtonField.CustomAttributes.Add(attr);

这是输出:

        private IWebElement saveButton_;
        [FindsBy()]
        public IWebElement saveButton
        {
            get
            {
                return saveButton_;
            }
            set
            {
                saveButton_ = value;
            }
        }