使用ASP.NET Core Identity,我再次查看了GitHub 上的源代码,在课堂上看到了IdentityResult以下几行:
public class IdentityResult
{
private List<IdentityError> _errors = new List<IdentityError>();
...
public IEnumerable<IdentityError> Errors => _errors;
...
}
当然,这可能是断章取义,但是,我不明白为什么需要创建一个单独的字段_errors,然后,为了获取它的值,单独创建一个属性Errors (是的,如果我没记错的话,这是一个属性,而不是一个方法)而不是仅仅写:
public List<IdentityError> Errors { get; } = new List<IdentityError>();
我会理解它是否是某种遗留代码,但毕竟.NET Core.
这种分离的意思是只给出了列表枚举的可能性,而不是它的修改。
在您的版本中,类外部的代码将能够更改错误列表。
然后IList接口的修改集合的方法将从外部可用:
Clear、Add、Remove。显然,代码的作者不希望任何人能够进行更改,因此该集合
Errors仅可用于通过IEnumerable接口进行枚举,该接口不包含能够进行更改的方法。确定了在框架中使用的两个优点。
你的例子:
查看访问修饰符,即具体类型(1)
private。好抽象合约(2)public。这是进一步更改的本地化,以免受到另一个模块的影响。也就是我们可以List<T>改成Stack<T>不会影响其他客户端的,也就是本地化的(这里隐含了松耦合(也就是作者保证))。这打破了信息隐藏,因为它返回了一个数据结构。所以它使用枚举类型
IEnumerable<T>来隐藏内部数据,这样客户端就不会操作Remove,Update,Add. 也就是说,可以使用克隆,但这是一项昂贵的操作(RAM 等),因此这里使用了信息隐藏(高级抽象接口枚举)IEnumerable<T>(仅用于枚举访问)。PS本地化:当有变化时,变化会在一个地方或者变化最小化。