你写的return null正确吗?
上次一篇“你写的try…catch真的有必要吗”引起了很多朋友的讨论。本次我在code review又发现了一个问题,那就是有人有意无意的写出了return null这样的代码,例如:
public User GetUser(Guid userId)
{
if ( /*for some reason*/)
return null; return DB.GetByUserId(userId);
}
这样的写法有木有问题?
在我看来没有充分的理由不应该返回null,因为方法的使用者并不知道在何种条件下会得到null,从而导致臭名昭著的NullReferenceException异常。
如果由于其他原因导致无法得到一个User,我们应该抛出一个明确的异常供上层服务决定如何处理:
public User GetUser(string userName, string password)
{
if ( /*for some reason*/)
return new SpecificException("can't get this user because ...."); return DB.GetByUserId(userId);
}
在我读过的开源项目中我几乎没有见到过return null的写法。能让我一时想到的两个linq方法FirstOrDefault()和LastOrDefault(),这两个方法通过命名的方式提醒使用者该方法会返回null。
说到FirstOrDefault()方法让我想起了很多人容易犯的另一个错误:
public User GetUserById(Guid userId)
{
return list.FirstOrDefault(x=>x.UserId==userId);
}
在确认数据库中该userId必须对应一个User的情况下使用FirstOrDefault()方法,此种场景我会建议你果断使用Single()方法。因为此时使用FirstOrDefault()会隐藏bug。你期望该userId必须得到一个User,如果Single()方法抛出异常则说明有bug出现,并且让你在第一时间发现该bug。
F#为了减少null类型的使用引入了option类型,在将option用作函数的返回类型时,如果没有对未定义的类型做处理,编译器会报错。
let invalidInt = None match invalidInt with
| Some x -> printfn "the valid value is %A" x
| None -> printfn "the value is None"
如果此处的模式匹配忘记编写None->分支,编译器将会报错,从而提醒你必须处理invalidInt值为None时的逻辑。但是在C#中使用null类型,编译器给予不了我们帮助,所以我们应该避免return null这样的代码,你觉得呢?
刚才搜了一下stackoverflow,发现一篇很有意思的讨论 Should a retrieval method return 'null' or throw an exception when it can't produce the return value? 我觉得里面的回答比较准确。
你写的return null正确吗?的更多相关文章
- Intellij Idea 12 开发Android 报Caused by: java.lang.UnsatisfiedLinkError: FindLibrary return null;
这次开发是用的百度地图api,导入两个so文件,结果启动的时候总是报Caused by: java.lang.UnsatisfiedLinkError: findlibrary return null ...
- delete attempted to return null from a method with a primitive return type (int)
今天被自己给蠢死了 今天在代码中遇到这个错误, 百度翻译一下:映射方法,从一org.system.mapper.child.chmorganizationexaminationmapper.delet ...
- 在Java中,return null 是否安全, 为什么?
Java代码中return value 为null 是不是在任何情况下都可以,为什么不会throw NullPointerException? Java语言层面:null值自身是不会引起任何问题的.它 ...
- mybatis查询时使用基本数据类型接收报错-attempted to return null from a method with a primitive return type (int)
一.问题由来 自己在查看日志时发现日志中打印了一行错误信息为: 组装已经放养的宠物数据异常--->Mapper method 'applets.user.mapper.xxxMapper.xxx ...
- [LeetCode OJ] Linked List Cycle II—Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- js中return false; jquery中需要这样写:return false(); Jquery 中循环 each的用法 for循环
js中return false; jquery中需要这样写:return false(); Jquery 中循环 each的用法 $(".progressName").each(f ...
- Unity中yield return null和yield return WaitForEndOfFrame的区别
2017/07/04修改 - 对WaitForEndOfFrame的LateUpdate时序进行说明. 测试结论: 1.如果只是等待下一帧执行,用yield return null即可.调用顺序在Up ...
- rg.apache.ibatis.binding.BindingException: Mapper method 'com.dao.Cameao.getOnlineDayRation attempted to return null from a method with a primitive return type (float)
本文为博主原创,未经允许不得转载: 异常展示如下: org.apache.ibatis.binding.BindingException: Mapper method 'com.dao.Cameao. ...
- How to return NULL string
Q: std::string get_file_contents(const char *filename) { std::ifstream in(filename, std::ios::in | s ...
随机推荐
- MJPhotoBrowser BUG修复
崩溃在loading.progress = (float)receivedSize/expectedSize; 分析:MJPhotoView 执行了hide移除了MJPhotoLoadingView, ...
- DAP in Coresight
DAP简单来说分成 DP + AP , Debug Port + Access Port Debug Port--和JTAG的接口叫做Debug Port Access Port--和内部其他的接口叫 ...
- c# 写着玩的,两个Task并发,一个写队列一个读队列的异常情况
class Program { class TestEnqueue { static Queue<string> str = new Queue<string>(); publ ...
- vios 虚拟光驱 安装vioc
一.VIO server 创建虚拟光驱 1 检查是否创建Library $lsrep 2 创建 VMLibrary :vg 和size都可以自己定义 $mkrep -sp rootvg -size 1 ...
- 深入浅出UML类图(一)
在UML 2.0的13种图形中,类图是使用频率最高的UML图之一.Martin Fowler在其著作<UML Distilled: A Brief Guide to the Standard O ...
- java线程池初步理解
多线程基础准备 进程:程序的执行过程,持有资源和线程 线程:是系统中最小的执行单元,同一个进程可以有多个线程,线程共享进程资源 线程交互(同步synchronized):包括互斥和协作,互斥通过对象锁 ...
- Php 笔记
php基本简介 为何要学习php 通过上网查资料,了解了基本的php知识,并知道了php的优缺点.php是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要适用 ...
- 四川软件人才网:打造四川最专业的IT人才招聘平台
四川软件人才网(www.tfsp.net),原名:天府软件人才网:为了更好的发展和拓展的业务需要,更名为:四川软件人才网,强力打造四川最专业的IT人才的招聘平台. 网站依托四川软件人才社区,微博,微信 ...
- SQL事物隔离级别
标准SQL定义了4个隔离级别 Read uncommitted 未提交读 Read committed 已提交读 Repeatable read 可重复读 Serializable 可序列化 基本语法 ...
- c#对数据库访问完应关闭连接
1.对数据库的连接SqlConnection con = new SqlConnection(constr);使用完成后,应该至少应该close或dispose关闭.否则会导致数据库例如(SQl200 ...