C# 如何查看类的所有实例?
我在学校做了一个关于类间关系(UML)的简短介绍,我想用代码展示组合和聚合在实际使用中是如何工作的,以及它们之间的区别。然而,为了做到这一点,我希望能够看到所有活动对象,证明我删除的对象和它的一部分对象现在真的消失了 这是我尝试做的一个快速示例:C# 如何查看类的所有实例?,c#,uml,C#,Uml,我在学校做了一个关于类间关系(UML)的简短介绍,我想用代码展示组合和聚合在实际使用中是如何工作的,以及它们之间的区别。然而,为了做到这一点,我希望能够看到所有活动对象,证明我删除的对象和它的一部分对象现在真的消失了 这是我尝试做的一个快速示例: List<Company>companies = new List<Company>(){ new Company(){ Name = "Greiner", new Boss(){
List<Company>companies = new List<Company>(){
new Company(){
Name = "Greiner",
new Boss(){
Name = "Hugo",
},
},
};
Company comp = companies.FirstOrDefault();
companies.Remove(comp);
Listcompanies=newlist(){
新公司({
Name=“Greiner”,
新老板(){
Name=“雨果”,
},
},
};
Company comp=companys.FirstOrDefault();
公司。移除(公司);
现在,我想以某种方式表明老板与公司是一致的,而不仅仅是(间接)提及他。所以我想看看所有的活动物体
有没有办法做到这一点?我知道垃圾收集器应该这样做,但我不想告诉我的同学们相信我的话
此外,我确实倾向于认为过于复杂,因此我的方法可能完全是倒退的,因此任何关于如何证明聚合和组合之间的差异的建议都是受欢迎的
问候
Andreas Postolache您可以在类中保留一个静态计数器,以记录创建的实例数。在构造函数中递增此计数器,在析构函数中递减。下面显示了类结构示例
public class Company
{
public static int counter = 0;
public Company()
{
counter++;
}
public string Name {get;set;}
public Boss Boss { get; set; }
~Company()
{
counter--;
}
}
public class Boss
{
public static int counter = 0;
public Boss()
{
counter++;
}
public string Name {get;set;}
~Boss()
{
counter--;
}
}
现在,您可以通过在需要时打印此计数器来查看实例数
现在可以实例化类公司并检查对象的计数
Company company = new Company(){ Name = "Greiner", Boss = new Boss(){ Name = "Hugo" }} ;
Console.WriteLine("Company: " + Company.counter.ToString());
Console.WriteLine("Boss: " + Boss.counter.ToString());
company = null;
输出结果应为Company:1和Boss:1
现在,单击一个按钮,编写以下代码
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Company: " + Company.counter.ToString());
Console.WriteLine("Boss: " + Boss.counter.ToString());
请注意,您必须调用垃圾收集方法来强制立即收集,否则无法保证GC何时删除该对象
现在,公司和老板的输出都将显示0
<>注释:使用GC。只在课堂上收集演示。 <垃圾收集在这里为你复杂化——也许在本机C++中显示这一点更有意义。但是,可以显式调用GC.Collect()强制垃圾收集。要跟踪对象的删除,可以使用析构函数:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ExampleDeletion
{
class Program
{
public class Company
{
public string Name { get; set; }
public Boss CEO { get; set; }
~Company()
{
Console.WriteLine("Company destroyed: " + Name);
}
}
public class Boss
{
public string Name { get; set; }
~Boss()
{
Console.WriteLine("Boss destroyed: " + Name);
}
}
static void Main(string[] args)
{
List<Company> companies = new List<Company>();
Add(ref companies);
Remove(ref companies);
GC.Collect();
Console.ReadLine();
}
static private void Add(ref List<Company> companies)
{
companies.Add(
new Company()
{
Name = "Greiner",
CEO = new Boss()
{
Name = "Hugo"
}
});
}
static private void Remove(ref List<Company> companies)
{
Company comp = companies.FirstOrDefault();
companies.Remove(comp);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间示例删除
{
班级计划
{
公营公司
{
公共字符串名称{get;set;}
公共Boss CEO{get;set;}
~Company()
{
Console.WriteLine(“公司销毁:+名称”);
}
}
公务舱老板
{
公共字符串名称{get;set;}
~Boss()
{
Console.WriteLine(“Boss销毁:+名称”);
}
}
静态void Main(字符串[]参数)
{
上市公司=新上市公司();
添加(参考公司);
移除(参考公司);
GC.Collect();
Console.ReadLine();
}
静态私有作废添加(参考列表公司)
{
公司。添加(
新公司()
{
Name=“Greiner”,
首席执行官=新老板()
{
Name=“雨果”
}
});
}
静态私有无效删除(参考列表公司)
{
Company comp=companys.FirstOrDefault();
公司。移除(公司);
}
}
}
在尝试此方法时,我注意到一件有趣的事情,即如果在创建该项的同一范围内从列表中删除该项,则它不会被GC收集。看起来有一个来自当前作用域的隐式引用使对象保持活动状态。这就是我将项目的创建推到一个单独功能的原因。我可能误解了你的问题,但我认为你的观点是错误的。您的类组合应该表示支持数据的性质(通常在数据库中)。它不应该在运行时被粗暴地修改以反映您的数据。您最好修改备份数据并将数据反映到UI,而不是修改代码结构。当您在同一段中谈到垃圾收集器时,您所说的“…显示…”是什么意思??你想展示什么?内存管理是如何工作的?然后:它与UML有什么关系?我有一个UML模型,其中Boss和公司有一个组合关系,就像Boss是公司的一部分一样。我还有这个模型的代码实现。当我删除Company对象时,Boss对象也应该被删除,因为这个关系。我想证明它真的消失了,甚至从记忆中消失了。看看下面Praveen Paulose的答案,基本上已经回答了,只是出于某种原因,我的小测试项目还没有开始工作。谢谢你,这是一种简单易懂的方法,非常适合做一个简短的演示。问题是,我的垃圾收集器似乎并没有做好他的工作。析构函数从未被调用。我确定打电话给Garbacollector,但他仍然没有删除对象。哦,我肯定会的,我只是想知道你是否知道为什么我的垃圾收集器没有实际删除对象。从理论上讲,它应该可以工作,但是GC不能这样做。在将对象设置为null的方法之外调用GC。例如,在表单Load中,您编写类初始化和销毁。单击一个按钮,将代码添加到GC.Collect并等待挂起的终结器。如果在同一个方法中使用,GC将保留引用,并且不会将其标记为删除/清除。