2
class UserDatastore : IUserDatastore
{
    ...

    public IUser this[Guid userId]
    {
        get
        {
            User user = (from u in _dataContext.Users
                             where u.Id == userId
                             select u).FirstOrDefault();

            return user;
        }
    }

    ...
}

我们团队中的一位开发人员认为,在上述情况下使用索引器是不合适的,GetUser(Guid id)应该首选一种方法。

论据是:

1) 我们没有对内存中的集合进行索引,索引器基本上是在执行隐藏的 SQL 查询 2) 在索引器中使用 Guid 是不好的(FxCop 也标记了这一点) 3)null从索引器返回不是正常行为4) API 用户通常不会期望任何这种行为

我在一定程度上同意(大部分)这些观点。

但我也倾向于争辩说,Linq 的一个特点是抽象数据库访问以使您看起来只是在处理一堆集合,即使惰性评估范式意味着这些集合不被评估直到您对它们运行查询。以与此处具体的内存中集合相同的方式访问数据存储区对我来说似乎并不矛盾。

还要记住,这是一个继承的代码库,它广泛且一致地使用这种模式,是否值得重构?我接受从一开始就使用 Get 方法可能会更好,但我还不相信使用索引器是完全不正确的。

我很想听听所有的意见,谢谢。

4

2 回答 2

0

我认为他关于使用 GUID 作为索引器的观点可能是指它存储在数据库中。使用整数作为键将提供更好的性能,并且比使用 GUID 占用更少的存储空间。

如果索引(键)不在集合中,那么通常使用索引器返回 null 是非常少见的,那么您会抛出异常。

就我个人而言,我并没有真正看到这里的问题,无论如何它几乎等同于拥有一种GetUser方法。我的意思是,如果您想稍微整理一下,您实际上可以引入一个称为GetUser索引器可以调用的私有方法,例如

public IUser this[Guid userId]
{
    get { return GetUser(userId); }
}

private IUser GetUser(Guid userId)
{
    return (from u in _dataContext.Users 
            where u.Id == userId 
            select u).FirstOrDefault();
}

从设计的角度来看,我个人不会使用索引器,我会使用一种GetUser方法。

于 2010-04-15T10:56:06.437 回答
0

我倾向于同意您的团队开发人员建议的几乎所有内容,除了Guid部分。如果这里有任何问题,考虑到性能,它必须在数据库级别,而不是在您的代码中。

我个人认为属性和索引器不应该隐藏长时间运行的操作,尽管它们Users可以被 LINQ-to-SQL 缓存。这就是为什么我也更喜欢一种方法。

我也同意从索引器返回 null 是不好的。改为抛出异常。

于 2010-04-15T11:03:57.580 回答