C# 在运行时编写和更改代码

C# 在运行时编写和更改代码,c#,code-generation,reflection.emit,codedom,roslyn,C#,Code Generation,Reflection.emit,Codedom,Roslyn,我想在运行时使用EditorFor/DisplayFor模板(或类似的东西)构建MVC样式的视图 理想情况下,我们的应用程序将允许用户选择他们想要在UI中的字段(以便他们可以添加/删除任何他们认为合适的字段),为此,我认为在运行时创建viewmodel classess并根据用户选择(即stringlength、required等)向其添加各种dataannotation属性会很方便 我需要能够支持的一件事是在运行时更改生成的类,而不影响其他用户或必须执行完整的iisreset 为此,我做了一些

我想在运行时使用EditorFor/DisplayFor模板(或类似的东西)构建MVC样式的视图

理想情况下,我们的应用程序将允许用户选择他们想要在UI中的字段(以便他们可以添加/删除任何他们认为合适的字段),为此,我认为在运行时创建viewmodel classess并根据用户选择(即stringlength、required等)向其添加各种dataannotation属性会很方便

我需要能够支持的一件事是在运行时更改生成的类,而不影响其他用户或必须执行完整的iisreset

为此,我做了一些研究,似乎有3种不同的方法,CodeDom、RunSharp/relefection.Emit和Roslyn

据我所知,reflection.Emit/Runsharp允许我创建类,并在运行时向它们添加属性和属性,还可能在需要时修改它们,而不会产生负面影响

我不确定Roslyn是否会允许这样做,我还没有找到创建包含属性或属性的类的简单示例,我还看到一些人提到Roslyn的输出是不可变的,所以我不确定如何允许我在以后修改它而不产生负面影响

总的来说,从我所看到的情况来看,大多数人都不推荐CodeDom,所以我不完全确定我是否应该沿着这条路线走下去


有谁能告诉我这些方向中的哪一个对我来说是可行的吗?

因此,这些解决方案都不起作用,老实说,在运行时生成类型并不是您想要的

当涉及CLR时,一旦您拥有一个包含字段和方法的类型,您就不能在运行时真正添加新成员或更改成员。我们最接近做到这一点的是VisualStudio中的“编辑并继续”功能,我们对所能做的更改有很大的限制。我们经常通过不在您认为它们添加的地方添加方法或属性来“欺骗”,但我们将它们隐藏在其他地方,并在您进行编辑时发出引用此秘密位置的IL。完全不支持删除成员之类的疯狂行为。即使支持它,很多代码都喜欢假定执行
someObject.GetType().GetMembers()
会反复返回相同的内容

就Roslyn而言,当我们说结果是“不可变的”时,我们并不意味着对您可能生成的任何IL提出任何要求。相反,当您要求Roslyn解析某些东西或分析源代码时,对象(语法树、类型信息等)是不可变的。不过,这并不重要,因为一旦类型存在,就不能修改CLR中的类型


我同意斯维克的意见——这不是你想做的。在运行时使用一些适当的数据结构来表示您的信息,而不是试图将其视为可以以某种方式进行变异的具体类。

您确定确实需要在运行时创建类型吗?像
Dictionary
这样的东西就足够了吗?Interstating,是的,因为我已经做了更多的研究,它开始认为,如果我们不要求用户能够在运行时更改类型,那么我只需要在代码中有我自己的预构建类,所以我的想法是尝试通过动态创建整个类来尽可能多地复制它,然后我可以利用MVCs对模板对象的反射,并使用RavenDB来存储它们,而无需进行太多修改如果你需要动态的东西,只需在类型中使用Dictionary,不用担心传统意义上的类型安全性。是的,我想我使用的是一个具有Key(string)属性和Value属性(object)的类,主要是由于MVC中Dictionary绑定的一些问题,我意识到,只要我能用这种方法通过反思来告诉它,我并不真正在乎它是什么类型