基于不要返回null之EmptyFactory的应用详解
基于不要返回null之EmptyFactory的应用详解
发布时间:2016-12-28 来源:查字典编辑
摘要:有很多书上都提出过一个建议:不要返回null对象。比如下面的GetUsers方法:publicclassUser{publicstringI...

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

比如下面的GetUsers方法:

public class User

{

public string Id { get; set; }

public string Name { get; set; }

}

public List<User> GetUsers()

{

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

// search db for user

return result;

}

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

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 : IEnumerable, new()

{

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<Type, object> cacheEmptyObjects =

new Dictionary<Type, object>();

public static T Empty<T>() 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;

}

}

}

测试代码如下:

基于不要返回null之EmptyFactory的应用详解1

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

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

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

代码如下:

复制代码 代码如下:

public static class EmptyFactory<T> where T : IEnumerable, new()

{

private static Dictionary<Type, T> cacheEmptyObjects = new Dictionary<Type, T>();

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;

}

}

}

使用的时候,只需要

基于不要返回null之EmptyFactory的应用详解2

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

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

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

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新C#教程学习
热门C#教程学习
编程开发子分类