当前位置: 移动技术网 > IT编程>开发语言>c# > 基于不要返回null之EmptyFactory的应用详解

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
有很多书上都提出过一个建议:不要返回null对象。比如下面的getusers方法:public class user{    public s
有很多书上都提出过一个建议:不要返回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;
        }
    }
}

测试代码如下:

 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>对象。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网