我想要做的是读取C#代码,解析它,插入一些方法调用并最终编译它.
是否可以将C#源代码(字符串列表)转换为CodeDOM对象?
我想使用创建枚举CodeDom API.我在互联网上搜索得足够多,而且我得到的结果几乎没用.
我想要产生的是
public enum bug_tracker_type
{
[Description("Bugzilla")]
Bugzilla,
[Description("Debbugs")]
Debbugs,
[Description("PHP Project Bugtracker")]
PHP_Project_Bugtracker,
[Description("Google Code")]
Google_Code
}
Run Code Online (Sandbox Code Playgroud)
我使用CodeTypeDeclaration并将其IsEnum属性设置为true,创建了一个名称,并设置了它的属性.
现在最大的问题是如何填充身体?
我试过了
CodeTypeMember mem = new CodeTypeMember();
mem.Name = WadlSharpUtils.CreateIdentifier(discreteValue.value);
mem.CustomAttributes.Add(new CodeAttributeDeclaration(discreteValue.value));
// enumCandidate is an instance of CodeTypeDeclaration
enumCandidate.Members.Add(mem);
Run Code Online (Sandbox Code Playgroud)
虽然使用这个解决方案我可以生成描述属性,但行结束;与否,
表达式树和CodeDom之间有什么区别?我应该在哪种情况下使用哪个?
我正在开发一个C#应用程序,它允许用户基本上导入数据表,然后用迷你语言输入他们自己的公式,从底层数据计算新列.
这些公式被编译到引擎中的LINQ表达式树中,然后.NET 4.0表达式树库可能会编译成IL,因此可以执行它们.
我们最近开始使用我们的引擎获取一些高容量的滴答数据,我们发现这些编译的表达式树的速度是一个真正的瓶颈 - 在动态重新计算所有这些列时速度相当慢.使用内置的Visual Studio 2010探查器进行攻击,可以看出我们所有执行时间的一半都花在了clr.dll中,这个方法名为JIT_MethodAccessAllowedBySecurity.
粗略的谷歌搜索这个字符串并没有产生任何东西,所以我想知道是否有人可以告诉我这个方法是什么,以及是否有办法让它不吃掉我所有的周期?也许有一种方法可以编译这段代码并明确授予它做任何想做的事情,这样clr可以停止这些检查吗?也许表达式树引擎生成的临时程序集没有完全信任?
无论如何,我几乎不知所措,我很想知道其他任何StackOverflow'ers过去是否遇到过这个问题.提前致谢!
所以我有一个用C#编写的CodeDOM编译器,它应该根据其中一个资源编译另一个应用程序.我如何更改资源(或编译器的输出可执行文件)的目标.NET框架?
我想正确缩进文本文件中包含的一些VB.NET代码.有办法做到这一点吗?
例如从这开始:
Public Shared Function CanReachPage(page As String) As Boolean
Try
Using client = New WebClient()
Using stream = client.OpenRead(page)
Return True
End Using
End Using
Catch
Return False
End Try
End Function
Run Code Online (Sandbox Code Playgroud)
完成这个:
Public Shared Function CanReachPage(page As String) As Boolean
Try
Using client = New WebClient()
Using stream = client.OpenRead(page)
Return True
End Using
End Using
Catch
Return False
End Try
End Function
Run Code Online (Sandbox Code Playgroud)
到目前为止,我搜索过的所有内容都引导我使用IndentedTextWriter类,但我发现的唯一示例是手动缩进这样的行:.NET Console TextWriter,它理解缩进/ Unindent/IndentLevel
额外的功劳:如果可能的话,我还想添加正确的间距:
例如Dim i As String="Hello"+"GoodBye" - > …
我正在尝试使用以下代码解析simple.cs源文件:
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
var compileUnit = provider.Parse(File.OpenText(filename));
Run Code Online (Sandbox Code Playgroud)
这给了我一个NotImplementedException:
"此CodeDomProvider不支持此方法"
是不是.NET不提供解析C#代码的实现?或者我只是以错误的方式使用这个类?
编辑:这样做的原因是我想玩一些静态代码分析方法.我的研究不需要编译或执行代码.
我有一种情况需要生成一个带有大字符串const的类.我控制之外的代码导致我生成的CodeDom树被发送到C#源,然后被编译为更大的Assembly的一部分.
不幸的是,我遇到这种情况,如果这个字符串的长度超过Win2K8 x64中的335440个字符(Win2K3 x86中的926240),则C#编译器会以致命错误退出:
MSDN称CS1647是"编译器中的堆栈溢出"(没有双关语!).仔细观察我已经确定CodeDom"很好地"将我的字符串const包装在80个字符处.这导致编译器连接4193个字符串块,这显然是x64 NetFx中C#编译器的堆栈深度.CSC.exe必须在内部递归计算此表达式以"重新水化"我的单个字符串.
我最初的问题是:"有没有人知道改变代码生成器如何发出字符串的解决办法? "我无法控制外部系统使用C#source作为中间件的事实,我希望这是一个常量(而不是而不是字符串的运行时串联).
或者,我该怎么制定这个表达式使得一定数量的字符后,我仍然能够创造一个恒定的,但它是由多个的大型块?
完整的repro在这里:
// this string breaks CSC: 335440 is Win2K8 x64 max, 926240 is Win2K3 x86 max
string HugeString = new String('X', 926300);
CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
CodeCompileUnit code = new CodeCompileUnit();
// namespace Foo {}
CodeNamespace ns = new CodeNamespace("Foo");
code.Namespaces.Add(ns);
// public class Bar {}
CodeTypeDeclaration type = new CodeTypeDeclaration();
type.IsClass = true;
type.Name = "Bar";
type.Attributes = MemberAttributes.Public;
ns.Types.Add(type);
// public const string HugeString …Run Code Online (Sandbox Code Playgroud) 我有一种情况,我想将LinePragmas添加到CodeDom对象.但是一些代码dom对象具有LinePragma属性,而有些则没有.
所以我想知道是否可以使用dynamic关键字来检测对象上是否存在属性(不抛出异常),如果有,则添加pragma.这是我目前的方法:
public static T SetSource<T>(this T codeObject, INode sourceNode)
where T : CodeObject
{
codeObject.UserData["Node"] = sourceNode.Source;
dynamic dynamicCodeObject = codeObject;
// How can I not throw an exception here?
if (dynamicCodeObject.LinePragma != null)
{
dynamicCodeObject.LinePragma = new CodeLinePragma(
sourceNode.Source.Path.AbsoluteUri,
sourceNode.Source.StartLine);
}
return codeObject;
}
Run Code Online (Sandbox Code Playgroud)
更新: 我使用的解决方案是添加一个名为Exists()的扩展方法.我在这里写了一篇关于它的博客文章: 成员存在动态C#4.0
jist是创建一个扩展方法,返回一个实现DynamicObject的TryGetMember的对象.它使用反射然后返回true或false.这允许你编写这样的代码:
object instance = new { Foo = "Hello World!" };
if (instance.Reflection().Exists().Foo)
{
string value = instance.Reflection().Call().Foo;
Console.WriteLine(value);
}
Run Code Online (Sandbox Code Playgroud) 我有一个使用CodeDOM创建的类:
CodeTypeDeclaration some_class = new CodeTypeDeclaration("SomeClass");
// ... properties and methods creation elided
Run Code Online (Sandbox Code Playgroud)
我想创建一个"SomeClass"类型的List.但是,我似乎无法这样做:
var list_type = new CodeTypeReference(typeof (List<>).Name, ??? some_class ???);
var member_field = new CodeMemberField(list_type, field_name)
{
Attributes = MemberAttributes.Private,
};
Run Code Online (Sandbox Code Playgroud)
CodeTypeReference不接受a CodeTypeDeclaration,这是我需要的.我能做什么?我并不想通过类的字符串名字,因为这可能会导致错误.