博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不要返回null之EmptyFactory
阅读量:7015 次
发布时间:2019-06-28

本文共 2317 字,大约阅读时间需要 7 分钟。

有很多书上都提出过一个建议:不要返回null对象。

比如下面的GetUsers方法:

public class User

{

    public string Id { getset; }

    public string Name { getset; }

}

 

public List<User> GetUsers()

{

    List<User> result = new List<User>();

 

    // search db for user

    return result;

}

如果其他方法由GetUsersOfxxxGetUsersByXXX之类的方法,那么就有大量

List<User> result = new List<User>();

 

考虑到这一点,可以将new List<User>()  封装到方法中,这就是工厂模式了.

因为可能不是List<User> ,也许是Stack<User更或者是ObservableCollection<User>

 

所以配合泛型,代码如下:

public static class EmptyFactory

{

    public static T Empty<T>() where T : IEnumerablenew()

    {

        return new T();

    }

}

 

使用如下:

List<string> emptyList = new List<string>();

Stack<string> emptyStack = new Stack<string>();

ObservableCollection<string> emptyObserable = new ObservableCollection<string>();

 

emptyList = EmptyFactory.Empty<List<string>>();

emptyStack = EmptyFactory.Empty<Stack<string>>();

emptyObserable = EmptyFactory.Empty<ObservableCollection<string>>();

虽然这样写可以满足要求,但是可以发现基本没什么好处,写EmptyFactory还不如new 来得快。

不过如果能够缓存对象的话,也许EmptyFactory有作用。

考虑到这一点,为EmptyFactory增加缓存机制的代码如下,使用Dictionary<Type,Object> 来实现

 
public static class EmptyFactory
{
private static Dictionary
cacheEmptyObjects =
new Dictionary
();
 
public static T Empty
() where T : IEnumerable, new()
{
Type genericType = typeof(T);
 
if (cacheEmptyObjects.ContainsKey(genericType))
{
return (T)cacheEmptyObjects[genericType];
}
else
{
T tempEmptyObject = new T();
cacheEmptyObjects.Add(genericType, tempEmptyObject);
return tempEmptyObject;
}
}
}
 

 

测试代码如下:

 

 

不过这种方法有一个缺陷,对于值类型而言,需要装箱

其根本原因是因为EmptyFactory不知道T是什么,如果EmptyFactory知道T的话,那么就可以使用Dictionary<T,T> 的缓存了。

解决这个问题的思路是将EmptyFactory变成泛型类

代码如下:

 
public static class EmptyFactory
where T : IEnumerable, new()
{
private static Dictionary
cacheEmptyObjects = new Dictionary
();
 
public static T Empty()
{
Type genericType = typeof(T);
if (cacheEmptyObjects.ContainsKey(genericType))
{
return cacheEmptyObjects[genericType];
}
else
{
T tempEmptyObject = new T();
cacheEmptyObjects.Add(genericType, tempEmptyObject);
return tempEmptyObject;
}
}
}

 

使用的时候,只需要

当然也可以EmptyFactory<List<User>>.Empty();

 

为什么不用Enumersble.Empty<T>方法呢?

因为Enumerable.Empty<T> 返回的是IEnumerable<T>对象。

本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/09/27/2193644.html,如需转载请自行联系原作者
你可能感兴趣的文章
课程2:《黑马程序员_Java基础视频-深入浅出精华版》-视频列表-
查看>>
TP4056大电流1A使用注意事项
查看>>
java代理模式之静态代理
查看>>
ASP.NET MVC5+EF6+EasyUI 后台管理系统(80)-自由桌面
查看>>
Java常考面试题(四)
查看>>
前端学数据库之记录操作
查看>>
学习Javascript闭包(Closure)
查看>>
【Todo】git的fast forward & git命令学习 & no-ff
查看>>
如何远程关闭一个ASP.NET Core应用?
查看>>
共享内存mmap学习 及与 shmxxx操作的区别
查看>>
你性格那么软,总是经常改变想法
查看>>
Summary of Critical and Exploitable iOS Vulnerabilities in 2016
查看>>
NeHe OpenGL教程 第十七课:2D图像文字
查看>>
查看Linux系统版本与位数
查看>>
更换CentOS7的下载源为阿里云
查看>>
退出Android程序时清除所有activity的实现方法
查看>>
eclipse注释模板设置(未整理)
查看>>
Hibernate框架 主配置文件(Hibernate.cfg.xml)基本
查看>>
学习SpringMVC——从HelloWorld开始
查看>>
Say Hello to ConstraintLayout
查看>>