到目前为止,我已经做了一年的专业软件工程师,并获得了计算机科学学位。我知道c++和C中的断言有一段时间了,但直到最近才知道它们存在于c#和。net中。
我们的生产代码不包含任何断言,我的问题是这个…
我应该开始在我们的生产代码中使用断言吗?如果可以,什么时候使用它最合适?这样做会更有意义吗
Debug.Assert(val != null, "message");
or
if ( val == null )
throw new exception("message");
到目前为止,我已经做了一年的专业软件工程师,并获得了计算机科学学位。我知道c++和C中的断言有一段时间了,但直到最近才知道它们存在于c#和。net中。
我们的生产代码不包含任何断言,我的问题是这个…
我应该开始在我们的生产代码中使用断言吗?如果可以,什么时候使用它最合适?这样做会更有意义吗
Debug.Assert(val != null, "message");
or
if ( val == null )
throw new exception("message");
当前回答
我不知道它在c#和。net中是怎样的,但在C中assert()只在使用- ddebug编译时工作-如果没有编译,最终用户将永远不会看到assert()。仅供开发人员使用。我经常使用它,它有时更容易跟踪错误。
其他回答
将Debug.Assert()放在代码中任何需要进行完整性检查以确保不变量的地方。当编译Release版本时(即没有DEBUG编译器常量),对DEBUG . assert()的调用将被删除,因此它们不会影响性能。
在调用Debug.Assert()之前仍然应该抛出异常。断言只是确保在开发过程中一切都如预期的那样。
我不知道它在c#和。net中是怎样的,但在C中assert()只在使用- ddebug编译时工作-如果没有编译,最终用户将永远不会看到assert()。仅供开发人员使用。我经常使用它,它有时更容易跟踪错误。
您应该始终使用第二种方法(抛出异常)。
同样,如果你是在生产环境中(并且有一个发布版本),抛出一个异常(在最坏的情况下让应用程序崩溃)比处理无效值和可能破坏客户数据(这可能要花费数千美元)要好。
我不会在产品代码中使用它们。抛出异常,捕获和记录。
在asp.net中也需要小心,因为断言可以显示在控制台上并冻结请求。
所有的断言应该是代码,可以优化为:
Debug.Assert(true);
因为它检验的是你已经假设为真的东西。例如:
public static void ConsumeEnumeration<T>(this IEnumerable<T> source)
{
if(source != null)
using(var en = source.GetEnumerator())
RunThroughEnumerator(en);
}
public static T GetFirstAndConsume<T>(this IEnumerable<T> source)
{
if(source == null)
throw new ArgumentNullException("source");
using(var en = source.GetEnumerator())
{
if(!en.MoveNext())
throw new InvalidOperationException("Empty sequence");
T ret = en.Current;
RunThroughEnumerator(en);
return ret;
}
}
private static void RunThroughEnumerator<T>(IEnumerator<T> en)
{
Debug.Assert(en != null);
while(en.MoveNext());
}
在上面,有三种不同的空参数方法。第一个接受它为允许的(它只是什么都不做)。第二个则抛出异常供调用代码处理(或不处理,导致错误消息)。第三种假设它不可能发生,并断言它是这样的。
在第一种情况下,没有问题。
在第二种情况下,调用代码有一个问题——它不应该用null调用GetFirstAndConsume,所以它会返回一个异常。
在第三种情况下,这段代码有一个问题,因为在调用它之前,它应该已经检查过en != null,所以它不是真的是一个错误。或者换句话说,它应该是理论上可以优化为Debug.Assert(true)的代码,sicne en != null应该始终为真!