我用object != null了很多东西来避免NullPointerException.
有没有一个很好的替代品呢?
例如:
if (someobject != null) {
someobject.doCalc();
}
Run Code Online (Sandbox Code Playgroud)
NullPointerException当不知道对象是否存在时,这避免了a null.
请注意,接受的答案可能已过期,请参阅/sf/answers/167020941/以获取更新的方法.
我已经是一名专业软件工程师,已经有一年的时间了,已经获得了CS学位.我已经知道C++和C中有一段时间的断言,但直到最近才知道它们在C#和.NET中存在.
我们的生产代码不包含任何断言,我的问题是......
我应该在生产代码中开始使用Asserts吗?如果是这样,它的使用何时最合适?这样做会更有意义吗?
Debug.Assert(val != null);
Run Code Online (Sandbox Code Playgroud)
要么
if ( val == null )
throw new exception();
Run Code Online (Sandbox Code Playgroud) language-agnostic testing defensive-programming exception assertions
通过合同编程时,函数或方法首先检查其前提是否已满足,然后才开始履行其职责,对吗?两个最重要的方式做这些检查是通过assert和exception.
你觉得哪一个更好?
请参阅此处的相关问题
我看过这个问题,但还有几个关于assert关键字用法的问题。我正在与其他一些编码人员讨论如何使用assert. 对于此用例,有一种方法可以在满足某些先决条件时返回 null。我编写的代码调用该方法,然后断言它不返回 null,并继续使用返回的对象。
例子:
class CustomObject {
private Object object;
@Nullable
public Object getObject() {
return (object == null) ? generateObject() : object;
}
}
Run Code Online (Sandbox Code Playgroud)
现在想象我像这样使用它:
public void useObject(CustomObject customObject) {
object = customObject.getObject();
assert object != null;
// Do stuff using object, which would throw a NPE if object is null.
}
Run Code Online (Sandbox Code Playgroud)
有人告诉我应该删除assert,它们不应该用于生产代码,只能用于测试。真的吗?
我曾经在一家公司工作,其中一些主要架构师/开发人员已经强制要求断言不使用的各种项目,并且他们通常会从代码中删除并替换为异常.
我觉得他们在编写正确的代码时非常重要.任何人都可以建议如何证明这样的授权是合理的吗?如果是这样,断言有什么问题?
是否有任何库有助于在C++应用程序中通过契约原则实现设计?
特别是,我正在寻找一个可以使用原理的库,就像这样.
我正在开发一个生成设备报告的库.generate_report (const std::string& no)由于各种原因,成员函数可能会失败:
report_generator是FSM)哪种错误处理机制最适合这些错误?
true或false一些上下文信息:正常的工作流程如下.用户激活设备,从列表中选择报告并单击"生成".
编辑:感谢您的回复!对我来说,现在很清楚何时使用断言以及何时进行错误处理.至于错误处理,错误代码和异常都有利有弊.我想我会考虑异常(并为上述错误创建四个类),但我还不确定.我总是想到"意外情况"的例外情况.无效的报告编号并非真正意外.有什么建议?:)
令人惊讶的我才能够找到SO关于这个主题的一个先前的问题,我只是想获得社会"信任投票"(或不!)我的做法.
我这样看是这样的:
Debug.Assert你的处置将是真实的状态的事情.当我们完全控制我们的环境时,例如在验证某些前后条件的方法中,将使用此方法.在以下场景中它有点模糊.请注意,这是一个仅供参考的示例!
假设我们有MyClass类,它有一个公共属性MyMode和一个方法GetSomeValueForCurrentMode().将MyClass视为一个打算在库中发布(发布版本)以供其他开发人员使用的版本.
我们希望MyMode可以由此类的外部用户更新.现在,GetSomeValueForCurrentMode()有以下逻辑:
switch(MyMode)
{
case Mode.ModeA:
return val1;
case Mode.ModeB:
return val2;
default:
//Uh-uh this should never happen
}
Run Code Online (Sandbox Code Playgroud)
我在这里得到的是MyClass的用户将其置于无效状态.那我们该怎么办?
在默认情况下,我们应该Debug.Assert或throw new InvalidOperationException(或其他)?
有一句咒语说我们不应该信任我们班级的用户.如果我们选择Debug.Assert并将MyClass构建为发布版本(从而删除Debug Asserts),则该类的用户将无法获得他们将其置于无效状态的有用信息.但这与其他咒语相反,后者只表示在完全无法控制的事情发生时抛出异常.
我发现我围绕着这个问题 - 其中一个编程辩论似乎没有明确的'正确'答案.那么让我们投票吧!
编辑:我在相关的SO问题(使用断言或例外的合同设计?)中注意到了这个响应:
经验法则是,在尝试捕获自己的错误时应使用断言,在尝试捕获其他人的错误时应使用异常.换句话说,您应该使用异常来检查公共API函数的前提条件,以及何时获得系统外部的任何数据.您应该将断言用于系统内部的函数或数据.
对我而言,这是有道理的,并且可以与下面概述的'Assert then throw'技术结合使用.
欢迎思考!
一个方法论问题:
我正在使用node.js,mongodb和express.js为某些服务实现API接口.
在许多(几乎所有)网站上,我看到这样的代码:
method(function(err, data) {
assert.equal(null, err);
});
Run Code Online (Sandbox Code Playgroud)
问题是:我是否应该assert在生产时将代码保留在我的代码中(至少对于"低重要性"错误)?或者,这些仅用于测试代码,我应该每次更好地处理所有错误?
在阅读了一些关于异常滥用的线程之后(基本上说,如果函数前置条件不正确,你不想解开堆栈 - 可能表示你的所有内存都已损坏或同样危险)我正在考虑使用assert()更多经常.以前我只使用assert()作为调试工具,我认为这是很多C++程序员使用它的方式.我担心我的错误处理部分会被未来某个时候引入运行时构建的NDEBUG #define关闭.有没有办法绕过这个并让其他人对此有问题(即我应该担心它)?
谢谢,帕特
编辑:我正在阅读的线程的重点是,如果您的应用程序确实存在错误,那么展开堆栈可能会损坏系统,例如,如果析构函数将某些内容写入文件并且文件句柄已损坏.我不建议使用assert进行正常的错误处理.我目前的用例非常弱,但看看你的想法:
//check later code won't crash the system
if( buf.length() % 2 )
return false;
// do other stuff that shouldn't affect bufs length
//copy 2 bytes into buf at a time, if length is odd then don't know
//what will happen so use assert to make sure it can't damage anything
assert( !(buf.length() % 2) );
for( i = 0; i != buf.length(); i += 2 )
memcpy( buf + i, data, 2 ); …Run Code Online (Sandbox Code Playgroud)