- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在开发一种 API,它根据存储在 XML 文档中的一些预定义规则动态编译成程序集。
我很难尝试让 CodeDOM 使用装饰有自定义属性的公共(public) getter 和私有(private) setter 生成属性。
这就是我想要的:
[Conditional()]
public E3477 E3477 { get; private set; }
但是我得到了这个,这不好,因为我不希望 setter 公开暴露:
[Conditional()]
public E3477 E3477
{
get
{
}
set
{
}
}
这是我使用的代码:
var componentRef = string.Format( "E{0}", component.XPathSelectElement( "Element" ).Value );
CodeMemberProperty prop = new CodeMemberProperty();
prop.Name = componentRef;
prop.Type = new CodeTypeReference( componentRef );
prop.HasSet = true;
prop.HasGet = true;
prop.Attributes = MemberAttributes.Public;
CodeAttributeDeclaration conditionalAttr = new CodeAttributeDeclaration( "Conditional" );
prop.CustomAttributes.Add( conditionalAttr );
compositeElementClass.Members.Add( prop );
我所追求的在 CodeDOM 中是否可行?
Stack Overflow 上的社区告诉我使用 CodeDom 并创建程序集而不是使用 MSBuild,我最初尝试这样做但无法让它工作。
** 使用难以阅读的代码进行编辑以查看是否可以简化 **
string GenerateDataElementsCode()
{
CodeNamespace globalNamespace = new CodeNamespace();
globalNamespace.Imports.Add( new CodeNamespaceImport( string.Format( "{0}.DataElements", _project.Target.RootNamespace ) ) );
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add( globalNamespace );
CodeNamespace ns = new CodeNamespace( string.Format( "{0}.DataElements", _project.Target.RootNamespace ) );
var codesDoc = XDocument.Load( string.Format( @"{0}\{1}", _project.Source.RootPath, _project.Source.UNCL ) );
var doc = XDocument.Load( string.Format( @"{0}\{1}", _project.Source.RootPath, _project.Source.EDED ) );
foreach ( XNode node in doc.Descendants( "DataElement" ) )
{
CodeTypeDeclaration dataElementClass = new CodeTypeDeclaration()
{
Name = string.Format( "E{0}", node.XPathSelectElement( "Identifier" ).Value ),
IsClass = true
};
dataElementClass.Comments.Add( new CodeCommentStatement( node.XPathSelectElement( "Description" ).Value, true ) );
dataElementClass.BaseTypes.Add( "SimpleObject" );
CodeAttributeDeclaration dataElementAttr = new CodeAttributeDeclaration( "DataElement" );
dataElementAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Identifier" ).Value )
} );
dataElementAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Name" ).Value )
} );
dataElementAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Description" ).Value )
} );
CodeAttributeDeclaration dataElementFormatAttr = new CodeAttributeDeclaration( "DataElementFormat" );
dataElementFormatAttr.Arguments.Add(
new CodeAttributeArgument
{
Name = "Cardinality",
Value = new CodePrimitiveExpression( node.XPathSelectElement( "Cardinality" ).Value )
} );
dataElementClass.CustomAttributes.Add( dataElementAttr );
dataElementClass.CustomAttributes.Add( dataElementFormatAttr );
var codes = codesDoc.XPathSelectElements( "SimpleDataElements/SimpleDataElement/CodeLists/CodeList" ).Where( a => a.XPathSelectElement( "../../Code" ).Value == node.XPathSelectElement( "Identifier" ).Value );
if ( codes.Count() > 0 )
{
CodeTypeDeclaration codesClass = new CodeTypeDeclaration( "Codes" );
codesClass.Attributes = MemberAttributes.Static;
codesClass.IsClass = true;
foreach ( XNode codeNode in codes )
{
CodeMemberField con = new CodeMemberField( typeof( string ), string.Format( "Code{0}", codeNode.XPathSelectElement( "Code" ).Value ) );
con.Attributes = MemberAttributes.Public | MemberAttributes.Const;
con.InitExpression = new CodePrimitiveExpression( codeNode.XPathSelectElement( "Code" ).Value );
con.Comments.Add( new CodeCommentStatement( codeNode.XPathSelectElement( "Description" ).Value, true ) );
codesClass.Members.Add( con );
}
dataElementClass.Members.Add( codesClass );
}
ns.Types.Add( dataElementClass );
}
unit.Namespaces.Add( ns );
var provider = new Microsoft.CSharp.CSharpCodeProvider();
using ( var sourceCode = new StringWriter() )
using ( var indentedTextWriter = new IndentedTextWriter( sourceCode, " " ) )
{
// Generate source code using the code provider.
provider.GenerateCodeFromCompileUnit( unit,
indentedTextWriter,
new CodeGeneratorOptions() { BracingStyle = "C" } );
return sourceCode.GetStringBuilder().ToString();
}
}
最佳答案
正如其他人指出的那样,CodeDom 本身不支持私有(private) setter (IIRC,因为它不是一个适用于 CodeDom 提供的所有语言的概念)。
大多数解决方案建议将“{ get; private set; }”显式硬编码到片段表达式中,但如果您需要具有逻辑访问器,这并没有多大帮助。这是一种相关但不同的方法,可以让我解决类似的问题。它不是很漂亮,但可以解决问题:
给出了一些辅助类
public static class SnippetGenerator
{
private static CodeDomProvider codeGenProvider = CodeDomProvider.CreateProvider("CSharp");
private static CodeGeneratorOptions codeGenOptions = new CodeGeneratorOptions() { BracingStyle = "C", BlankLinesBetweenMembers = false };
private static StringWriter stringWriter = new StringWriter();
public static string GenerateSnippet(CodeTypeMember member)
{
codeGenProvider.GenerateCodeFromMember(member, stringWriter, codeGenOptions);
string snippet = stringWriter.ToString();
stringWriter.GetStringBuilder().Length = 0;
return snippet;
}
}
然后您可以将现有的 CodeDom 属性转换为您可以使用字符串操作进行后处理的片段:
CodeMemberProperty componentProperty = new CodeMemberProperty();
... //(build out your property)
// inject private scope onto setter
string propertySnippet = SnippetGenerator.GenerateSnippet(componentProperty);
propertySnippet = propertySnippet.Replace(" set\r\n", " private set\r\n");
CodeSnippetTypeMember propertySnippetMember = new CodeSnippetTypeMember(propertySnippet);
注意:可能有比包含“\r\n”(根据您的代/平台设置可能有所不同)更好的方法来删除集合,但这是确保它不是的简单方法抓取任何不正确的子字符串。选择最适合您项目的方式。
关于c# - 使用 CodeDOM 生成私有(private) setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24576062/
我使用 visual studio 发布选项向我的主机发布了我的网站。 我的主机使用 asp.net 4.5.1 框架。 它在本地运行良好,但在我发布之后,却出现了这个错误。 我的本地 visua
这是一个使用VS2015的WebApi项目。 重现步骤: 创建一个空的 WebApi 项目 将构建输出路径从“bin\”更改为“bin\Debug\” 运行 在我将构建输出路径从“bin\”更改为“b
我正在调查 System.CodeDom namespace用于独立于语言(至少在一定范围内)的源代码生成,我发现一些信息不鼓励使用 CodeDom . 我认为 this early blogpost
有人知道如何使用 CodeDom 调用基类的泛型方法吗? 我调用标准方法没有问题,但我找不到调用泛型的解决方案。 我用来调用标准基类方法 GetInstance 的代码: CodeAssignStat
如何使用 CodeDom 生成调用其他类 Constructor 的代码我找不到任何 CodeConstructorInvokeExpression。 最佳答案 我相信您正在寻找CodeObjectC
我有一个在 C# 中使用 WPF 的程序,它使用 .NET 4 Framework(不是客户端配置文件),它编译了一个名为“Source.txt”的源文件。但是,无论何时编译它,我都会收到此错误“错误
我需要向 CodeNamespace 添加一个类 (Type)。我已经编写了一个 C# 类,但我不想将其手动转换为 CodeDOM。有没有办法将现有的加载到 CodeTypeDeclaration。
我正在使用 CodeDom 生成稍后要编译的代码,并且我注意到某些结构会创建额外的括号集。虽然我知道它们不会影响任何东西,但它们看起来确实很奇怪。 执行此操作的代码示例是这样的: new CodeCo
我想为我的应用程序构建一个构建器,这是构建器的来源 using System; using System.Collections.Generic; using System.ComponentMode
我正在尝试使用 CodeDom 生成一些方法,但在为这些方法生成自定义属性时遇到问题。 我可以管理简单的空属性,比如 [DataMember()] 或带有字符串值参数的属性, [DataContrac
有没有办法使用 C# CodeDom 生成字典初始值设定项?这些是否受支持? 我想要: private IDictionary map = new Dictionary { { "Name",
在 visual studio 中,我可以单击“引用”>“添加引用”并从我的计算机浏览到现有的 .dll 文件。然后我可以按如下方式使用引用的 dll: dllNameSpace.dllClassNa
如标题所示,我正在尝试使用 CodeDom 在 C# 的数组中“嵌套”或创建数组。 这是我要复制的行: T.Invoke(null, new object[] { new string[] {} }
我有一个使用 CodeDom 创建的属性。如何将其设置为自动属性,而不是针对私有(private)成员添加 CodeFieldReferenceExpressions? 最佳答案 IIRC,CodeD
有没有办法用 CodeDom 生成类约束。 因为当我使用类似的东西时 var method = new CodeMemberMethod(); var genericParam = new CodeT
好的,我觉得我的问题的答案在网上,但我找不到。我要做的就是将一个文本资源文件添加到我正在使用 CodeDom 编译的程序中,然后在已编译的程序中访问该文本文件。为了添加嵌入式资源,我使用了以下代码:
我正在寻找为使用 codeDOM 生成的 exe 文件设置文件版本的任何方法。我的始终显示为 0.0.0.0。以编程方式显然是首选,但在这一点上,有总比没有好。 最佳答案 编译程序集的版本由 Asse
我从 SE 找到了使用 CodeDOM 的类名验证方法,并使用了它: System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentI
是否可以仅使用常规 .NET 中的 System.CodeDom 创建 Silverlight 应用程序(.xap 文件、testpage.html、ClientBin 旁边的内容资源、浏览器外设置等
在 StackExchange 上有几个与此类似的问题,但它们并未涵盖完全相同的情况。请在将其标记为重复之前通读它! 在 C# 中使用 CodeDom,我试图为字典生成一个初始化表达式。例如 Dict
我是一名优秀的程序员,十分优秀!