是否可以将实体框架日志记录设置为生产源代码中的调试窗口?

Fos*_*sna 8 c# logging entity-framework visual-studio-debugging

是否可以在生产源代码中使用此行?它产生了什么样的性能损失?我知道Debug.WriteLine不会发布到使用发布配置构建的程序集.

ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg);
Run Code Online (Sandbox Code Playgroud)

在调试模式下运行时,此行应将实体框架日志输出记录到Visual Studio调试控制台.

#if DEBUG 
ddiCatalogEntities.Database.Log = msg => Debug.WriteLine(msg);
#endif
Run Code Online (Sandbox Code Playgroud)

你喜欢上面的解决方案吗?

Mat*_*son 8

首先,请注意,您不能将正常委托指向方法ConditionalAttribute.

但是,您正在使用lambda,因此编译正常.但它实际编译到什么程序?

考虑以下代码:

Action<string> print = message => Debug.WriteLine(message);
print("TEST");
Run Code Online (Sandbox Code Playgroud)

对于调试版本,这将编译为:

Action<string> print = delegate (string message) {
    Debug.WriteLine(message);
};
print("TEST");
Run Code Online (Sandbox Code Playgroud)

对于发布版本,它编译为:

Action<string> print = delegate (string message) {
};
print("TEST");
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,都会创建并调用委托 - 因此在这两种情况下,您都将拥有委托创建和调用(参数被压入堆栈)的开销,即使发布版本实际上没有执行任何操作.

因此,对于您的情况,使用#if DEBUG与否的区别如下:

  • 如果您使用#if DEBUG那么根本没有开销,并且Log不会设置该属性.
  • 否则,您需要设置Log属性的开销,然后在调用它时不执行任何操作.

在许多情况下,开销很小,你不介意 - 而且确保Log属性总是设置为某些东西(默认为"不执行任何"委托)是非常好的,所以你不需要检查它每次引用它之前为null.

另一方面,使用#if DEBUG它会使正在发生的事情变得更加清晰.lambda和使用ConditionalAttribute交互定义的方法的方式并不完全明显!

所有这些都是一种迂回的说法:权衡利弊,做出自己的选择.;)