RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 595274
Accepted
Adam Shakhabov
Adam Shakhabov
Asked:2020-11-24 17:09:48 +0000 UTC2020-11-24 17:09:48 +0000 UTC 2020-11-24 17:09:48 +0000 UTC

在类构造函数中实现 ICollection 接口

  • 772

当我阅读各种教程和我们最喜欢的 StackOverflow 时,我经常看到这样的代码:

namespace MvcApplication2.Models
{
    public class Category
    {
        public int ID { get; set; }

        public string Name { get; set; }
    }

    public class Product
    {
        public ICollection<int> CategoryID { get; set; }

        public Product()
        {
            CategoryID = new List<int>();
        }
    }
}

解释为什么一个属性应该CategoryID声明为一个接口ICollection,如果它在构造函数中用List?

设计师试图通过这种方法避免什么?

我了解是否Product通过其构造函数将某种依赖项引入了该类。但这不存在。

我错过了什么概念点?

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    free_ze
    2020-11-24T17:21:01Z2020-11-24T17:21:01Z

    价值突出,客户代码不知道那里有什么List。也就是说,在架构师的左脚跟的要求下,新版本的库List可以被替换LinkedList,没有人会受到影响。它是对集合实现的抽象。

    • 11
  2. Sergey Teplyakov
    2020-11-29T15:36:48Z2020-11-29T15:36:48Z

    这里作者在理论上尽量遵循最少知识的原则,不暴露实现细节。

    也许这段代码是旧的或者所有的组件都没有显示,但在这个实现中设计不好。

    1. 该属性CategoryID是可变的。客户可以在那里记录null随后的倾斜NullReferenceException。

    2. 该属性仅试图隐藏实现细节,但做得很差。这在很大程度上取决于上下文,但至少有两种方法可以使这种设计一方面更严格,另一方面更简单。

    首先,您可以使类型不可变并在构造函数中获取集合。在这种情况下,该属性可以成为或CategoryID代替类型。ICollectionIReadOnlyCollectionIReadOnlyList

    其次,如果不能使类不可变,那么添加一个方法AddCategory并仍然使属性成为CategoryID类型是有意义的IReadOnlyCollection/IReadOnlyList。

    没有上下文很难说,但我总是对命名空间中这样的数据对象感到惊讶Model。命名空间名称中的模型告诉我,应用程序的全部本质、它的域对象、行为和各种花哨的东西都将隐藏在这里。当我在这样的命名空间中看到简单的数据对象时,我的期望与现实之间存在一些差异。

    换句话说,如果想要创建模型,那么完全隐藏内部而不是删除“真实列表类型”是有意义的。然后可以在不破坏现有客户端的情况下添加更多高级行为(一些按类别过滤的逻辑和其他东西)。

    现在谈谈这个话题:

    BCL 中的集合接口有点疯狂,因为现在很难说出它们的含义。这尤其适用于类型ICollection:这个集合是什么?它是可变的吗?似乎是的,有一个方法Add。但麻烦的是,数组还实现了ICollection<T>,其方法Add抛出异常。是的,那里有房产IsReadOnly,但是所有客户都确定要检查吗?

    好吧,当然,集合有方法Contains和Remove,但第一个给出 O(N) 的复杂性,这几乎总是不好的,第二个也不适用于所有集合。

    所以事实证明这个接口经常被这样使用 IEnumerable + Count,但在这种情况下,IReadOnlyXXX视图更适合。

    结论是:您需要了解您在隐瞒什么,对谁隐瞒,以及您是否在隐瞒任何事情。如果在应用程序中使用此代码,则有两种选择:如果类是数据存储,则使用特定的集合,或者完全隐藏集合并IReadonlyXXX使用专门的方法公开视图Add。

    • 5

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5