假设我有一个循环,它创建一个EF类的新示例,并在每次循环迭代中添加到databasde表中:
foreach (var record in records)
{
InvestmentTransactionStaging newRecord = new()
{
UserId = UserId,
InvestmentTransactionTypeId = interestRepaymentTransactionTypeId,
InvestmentEntityId = InvestmentEntityId,
Description = record.LoanReference,
Date = DateTime.Parse(record.Date),
};
_context.InvestmentTransactionsStaging.Add(newRecord);
}
现在通常,在我习惯的语言中,如php,在调用_context后销毁示例并不重要。. Add(),垃圾收集器会处理它。如果我像上面那样省略它,这是否会潜在地导致C#中的内存问题?我是否需要在每次迭代时销毁示例,如果需要,如何销毁?(我无法使用Disapose方法,因为它抱怨该方法不可用。
2条答案
按热度按时间kpbwa7wx1#
创建的对象在不再可访问时自动析构
这意味着,任何创建的对象,只有当运行代码仍然在大括号中时才有效,因为它是在那里示例化的
正如computercarguy所提到的(以及在注解中),* 说对象只存在于声明它的代码块中是不准确的 ,因为只要程序中有对它的引用,对象就存在。
也就是说,如果您声明了一个名为
newRecord
的示例,并且您没有将it赋给任何其他在声明newRecord
的代码块之外声明的指针,则当编译器退出该代码块时,会出现这种情况( 并经过垃圾收集的步骤),则将其从存储器中移除,但是如果存在另一个指针,例如oldRecord
,并且在代码块结束之前将newRecord
的值(地址)赋给它,则该对象不会从内存中删除,因为它仍然被指针ieoldRecord
指向。结论:The garbage collector checks for objects that are no longer being used by the application *,所以手动删除对象是没有意义的,因为如果删除对象是安全的,那么GC会为您做,因为由我们不完美的人来实现时可能会导致问题
hyrbngr72#
newRecord
设置为null,您也不会破坏类示例。它仍然可以在_context.InvestmentTransactionsStaging
对象中访问。(在本例中,_context
可能是一个数据库。)长回答:
我可能会在这里陷入困境,但您的变量只是一个指向创建类示例/对象的内存地址的指针。当您将该变量置空时,您只需要从变量中删除内存地址的值,而不是对象。如果其他变量指向同一内存地址,则对象将保留。当该对象'的内存地址不再被任何变量或其他对象指向。这是当事情被"破坏"的时候。
这种情况在许多现代语言中都会发生,而不仅仅是C#。C#中的情况可能与PHP中的情况不同,但最终的结果是相似的。
即使说对象被销毁也不是100%正确的,因为值通常不会被删除。内存地址只是用于其他用途,并在需要时被覆盖。它可以在同一个程序中,也可以返回到操作系统,以便分配给另一个进程。
这并没有涵盖对象的整个生命周期,但这是最有用的解释,除非你需要进入微控制器和其他嵌入式系统的低级别编程。