C# 在构造函数中返回新对象或初始化成员?

C# 在构造函数中返回新对象或初始化成员?,c#,performance,initialization,C#,Performance,Initialization,我们有一个数据提供程序类,它为数据库中的每个聚合返回存储库 让我们考虑下面的场景: public class DataProvider { public IBookRepository Books { get { retun new BookRepository(); } } public IAuthorRepository Authors { get { retun new AuthorRepository(); } } } 如您所见,每次调用成员时,我们都会返回给定对象的一

我们有一个数据提供程序类,它为数据库中的每个聚合返回存储库

让我们考虑下面的场景:

public class DataProvider {
    public IBookRepository Books { get { retun new BookRepository(); } }
    public IAuthorRepository Authors { get { retun new AuthorRepository(); } }
}
如您所见,每次调用成员时,我们都会返回给定对象的一个新实例:
DataProvider.Books.DoBANANAS()

vs

将调用'DataProvider.Books.BANANAS();现在CPU/内存的负担会减少吗

当我刚刚开始实现这两个版本时,它们令人惊讶地工作了


但我的经验告诉我。然而,我有足够的时间来充分优化和实现最终产品。(这是在研究小组工作的好处之一)

您的第一个示例每次都会创建XXXRepository对象的一个新实例,其中第二个实例会将句柄返回到已经存在的句柄,因此第二个实例的性能会更好,并且使用更少的CPU,因为不需要分配新内存


更大的问题是,除非存储库类完全是静态的,否则这两个场景会产生完全不同的结果。如果存储库类是数据库的某种接口,那么选项1不需要像选项2那样是线程安全的。

所示的实现在构造和管理对象的方式上有所不同。在第一个示例中,每次调用
数据提供程序
上的属性时,都会创建一个新的存储库。如果存储库持有任何状态(例如,已获取对象的缓存),您将获得与第二个示例非常不同的行为,因为每次都会将该状态重置为其默认状态

从您所说的两个版本都可以工作的事实来看,我冒昧地猜测,存储库对象不保持状态,只是数据库调用的代理。在这种情况下,可能不会有太大区别

然而,这两种方法的性能和内存配置非常不同。虽然过早优化是一件坏事,而且通常是浪费时间,但我不会将其归类为此类,因为在每次属性调用上创建新的存储库以后显然会出现性能问题,或者更糟糕的是,如果在存储库中引入状态,则会引入难以跟踪的bug。创建更少的对象最终会减少垃圾收集器的负担,但除非您创建数百万个对象,否则这将是一个微不足道的差别


总之,第二个例子是更好的一个,考虑到这一点,我认为现在没有什么真正的问题。

这两个例子在语义上是不相同的。它们有非常不同的行为,而不仅仅是内存使用或速度上的一些细微差异。我想你并不想知道第一个解决方案是什么。两个版本的行为都有很大的不同(至少在你的例子提供的细节层次上),这可能不仅仅是比较两个解决方案做不同的事情。你应该先确定具体的行为和语义,然后才考虑性能(如果且仅当它是一个实际问题)。谢谢你的回复。你猜对了,我的存储库根本没有状态。另一个问题:让数据提供者
静态
会有所不同吗?每次需要访问数据库或任何其他提供程序中的数据时,我不需要创建和实例化数据提供程序。这取决于具体情况。这可能会使获得
数据提供者变得更容易,但如果将其作为静态实例,则会使其更难测试。在阅读了更多关于该主题的内容(有假期,这就是延迟响应的原因)后,我发现我在无意识地尝试实现
UnitOfWork
原则。这正是我想要的,经过进一步研究,我发现这正是我想要的。再次感谢你的回答!
public class DataProvider {
    public IBookRepository Books { get; }
    public IAuthorRepository Authors { get; }

    public DataProvider()
    {
        Books = new BookRepository();
        Authors = new AuthorRepository();
    }
}