不要返回null之EmptyFactory

简介:

有很多书上都提出过一个建议:不要返回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<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;
        }
    }
}

 

测试代码如下:

 image

 

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

其根本原因是因为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;
        }
    }
}

 

使用的时候,只需要

image

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

 

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

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






本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/09/27/2193644.html,如需转载请自行联系原作者
目录
相关文章
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
|
SQL Oracle 关系型数据库
【问题处理】—— SQL里进行 null值 的判断永远返回 false?
【问题处理】—— SQL里进行 null值 的判断永远返回 false?
103 0
【TS】关于v-for数组对象遍历以及在页面上使用提示object类型的问题解决
【TS】关于v-for数组对象遍历以及在页面上使用提示object类型的问题解决
195 0
|
7月前
|
前端开发 数据库
返回参数不用实体类,用map返。resultType=“Map“,以及使用map不返回空的值解决办法,
返回参数不用实体类,用map返。resultType=“Map“,以及使用map不返回空的值解决办法,
222 1
|
存储 数据库
案例09-数据类型不一致导致equals判断为false
数据类型不一致导致equals判断为false
案例09-数据类型不一致导致equals判断为false
|
前端开发
根据数组code值返回value值
根据数组code值返回value值
79 0
|
存储 SQL API
VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
|
关系型数据库 MySQL
NULL 值处理
NULL 值处理
|
缓存 算法 JavaScript
为什么[null] === [null]输出为false❓
有人问,为什么null === null 输出值true,但是[ null ] === [ null ]输出值却是false?
167 0