在编译时运行代码

时间:2015-09-17 22:47:19

标签: c#

是否有可能在编译时执行某些代码?

例如,我想检查动态对象的请求方法是否存在于泛型类的参数类型中。

 //this code has no actual purpose, just as an example
 public class Sample<T>
 {
     public Sample<T>(T instance)
     {
         foo = Value = instance;
         /* adding some extra code(e.g. logging) to the methods of T, by
inserting a "M" in front of the method names of T */
     }

     public T Value { get; }
     public dynamic foo { get; }
 }

如何/可以使用

var foo = new Sample<string>("hey");
foo.MSubstring(0,0);

现在我想知道是否有可能在编译时执行代码,例如在运行时之前抛出异常,在{。

中不存在foo.MgetSize()

(这个问题只是关于如何在编译时执行代码,这个示例不是真正的问题。)

我没有计划如何做到这一点。也许使用那些#if - 东西?

5 个答案:

答案 0 :(得分:2)

是的,可以在构建时执行代码。毕竟,构建程序的工具本身就是代码。

您要问的是如何自定义构建过程并在其中执行一些额外的逻辑。如何执行此操作取决于您使用的实际工具 - 例如,对于Visual Studio和MSBuild系统,您可以参考MSDN documentation on custom build steps and build events

你的自定义构建工具将取决于它将在哪个部分启动。如果它与源代码一起工作,它需要能够解析C#源代码(也可能是VS项目文件) 。如果它通过验证发出的程序集(在典型的构建过程结束时生成的二进制文件)来工作,它可以简单地使用反射来检测您想要的错误。我会说后者更方便。

答案 1 :(得分:2)

理论上,您可以使用T4进行编译时检查 另一种方法 - 使用支持编译时宏的语言。例如Nemerle或Boo 也许你可以使用Roslyn。但仅限于C#6。

答案 2 :(得分:0)

在C#中,您可以运行一些您刚刚在&#34; Post Build&#34;中编译的代码。视觉工作室的一步。

您可以使用Post#等工具,通过创建执行检查的属性来执行您想要的操作。请参阅:https://www.postsharp.net/product/how-it-works

在其他语言中,如Jai,您可以轻松完成此操作。请参阅&#34;任意编译时代码执行&#34;,此处:https://sites.google.com/site/jailanguageprimer/

答案 3 :(得分:0)

某个功能可能存在且可能不存在的情况有点粗略。最好在接口中包含Convert方法,对象本身可以告诉您它是否实现了功能,并返回具有适当接口的对象,如果不是则返回null。

虽然可以用预处理器完成,但我不推荐。您描述的场景意味着您要包含一个标头,该标头确定该对象的方法,或者不包含该方法。你没有真正的动态。所以在标题中,使用

#define HASMETHOD

并在执行人中使用:

#ifdef HASMETHOD
   foo.MSubstring(0,0);
#endif 

但同样,STRONLY建议不要这样做。使用在运行时调用的方法来确定返回要调用的接口。

答案 4 :(得分:-1)

根据定义,您无法在编译时执行代码。但是,您可以使用静态构造函数在加载时执行代码(实际上在创建第一个实例之前或引用任何静态成员之前):

link to msdn