C#列出添加和获取参考

C#列出添加和获取参考,c#,list,C#,List,我正在使用C#编写一个包含类的唯一实例的列表。我想写一个函数来添加这个类的一个实例,并返回一个指向它的指针 public class Marble { public Marble(int ID) { // Initialize based on unique ID } } public class Bag { private List<Marble> marbles = new List<Marble>(); pub

我正在使用C#编写一个包含类的唯一实例的列表。我想写一个函数来添加这个类的一个实例,并返回一个指向它的指针

public class Marble 
{
    public Marble(int ID) 
    {
    // Initialize based on unique ID
    }
}

public class Bag 
{
    private List<Marble> marbles = new List<Marble>();
    public Marble Add(int ID) 
    { 
        Marble m = new Marble(ID);
        marbles.Add(m);
        return m;
    }
}
公共类大理石
{
公共大理石(内部ID)
{
//基于唯一ID初始化
}
}
公厕袋
{
私有列表大理石=新列表();
公共大理石添加(内部ID)
{ 
大理石m=新大理石(ID);
加上(m);
返回m;
}
}

这似乎比添加一个新的弹珠并搜索匹配的ID更优化。但是,弹珠m返回时是否会超出范围?据我所知,它只是一个指针的动态数组。如果大理石m不再存在,列表指针是否不再有效?

否,列表指针将正常。 该列表包含对您创建的大理石对象的引用,只要该列表包含该引用,而无需您的任何干预,该引用将始终有效

此外,如果您出于某种原因决定从列表中删除引用,而没有其他内容引用它,那么该引用将变得像一个悬空指针,并将由垃圾收集器自动收集,因此您也不需要进行清理

请记住,您的大理石实例是一个,这就是它的工作原理

对于习惯了C这样的语言的人来说,这听起来可能很神奇,除非将Marble放入堆中(通过new、malloc和它们的同类),否则您所做的事情将是一个问题

大理石
m
返回时是否会超出范围

是的,绝对会的。它是该方法的局部变量;它的作用域是用于该方法调用的,因此当该方法返回时,该变量超出了作用域。在这种特殊情况下,当该变量返回时,该变量的生存期也结束了,因此该变量将能够在该时间点被清除。从理论上讲,变量的生存期可能与其作用域不同,但在本例中并非如此。有关差异的详细分析,请参见

据我所知,它只是一个指针的动态数组。如果大理石m不再存在,列表指针是否不再有效

它绝对有效。丢失变量
m
只意味着一个引用不再存在;这并不意味着变量引用的对象不再存在


打个比方,把变量想象成一张纸。你在那张纸上写一个地址。接下来你把那张纸烧成灰烬。你的房子怎么了?你的房子什么也没发生;破坏一个对它的引用不会影响房子;如果你有房子的地址是出于其他原因(比如说你在烧掉它之前把地址复制到了另一张纸上),你仍然可以找到房子,并且销毁这张纸不会损坏房子。

只要有一个
Bag
的实例在某处被引用,该实例应该有大理石列表
Marble m
将是一个引用类型-当它从方法返回时不会超出范围。有关更多信息,请参阅Jon Skeet的这篇文章——在C#中,引用类型(在本例中是)将始终通过指针存储。不要担心东西被破坏,你有垃圾收集器来做这件事
return m
将返回指针,并且m将不会被销毁,直到您使用完它。