请大侠指出下面的代码有没有问题!
   主要是删除节点时内存会不会有卸漏?
//节点数据// 
public class TreeContainerNode
{ object data;
TreeContainerNode parent;
List<TreeContainerNode> childrens; public object Data
{
get { return data; }
set { data = value; }
}
public TreeContainerNode Parent
{
get { return parent; }
set { parent = value; }
}
public List<TreeContainerNode> Childrens
{
get { return childrens; }
set { childrens = value; }
} public TreeContainerNode(object data, TreeContainerNode parentNode, List<TreeContainerNode> children)
{
this.data = data;
this.parent = parentNode;
this.childrens = children;
}
}
//树型容器,树型 数据结构
public class TreeContainer
{
//
TreeContainerNode headNode; public TreeContainerNode HeadNode
{
get { return headNode; }
set { headNode = value; }
}
//指针//
private TreeContainerNode current;//当前节点
//构造 器
public TreeContainer(object data)
{
this.headNode = new TreeContainerNode(data, null, null);
this.current = this.headNode;
}
//移到上一节点
public bool MoveToParent()
{
if (current.Parent == null)
{
return false;
}
else
{
this.current = this.current.Parent;//移动
return true;
}
}
//移到子节点
///添
public bool MoveToChildren(int index)
{
if (this.current.Childrens == null)//没有子节点
{
return false;
}
if (this.current.Childrens.Count <= index)//没有这么多子节点
{
return false;
}
else
{
this.current = this.current.Childrens[index];
}
}
//添加子节点
public bool AddChildrenNode(object data)
{
//设为头节点
if (this.headNode == null)
{
this.headNode = new TreeContainerNode(data, null, null);
return false;
}
else
{
if (this.current.Childrens == null)//表示没有子节点
{
//创建子节点的容器
this.current.Childrens = new List<TreeContainerNode>();
//添加子节点数据
this.current.Childrens.Add(new TreeContainerNode(data, this.current, null));
}
else//表示 有字节点
{
this.current.Childrens.Add(new TreeContainerNode(data, this.current, null));
}
return true;
}
}
///删
//删除当前节点
public bool DeleteCurrentNode()
{
//没有父节点 当前节点就是根节点
//不能删除跟节点
//要删除,可以销毁本对象
if (this.current.Parent == null)
{
return false;
}
else
{
//删除并移到父节点
//记录
TreeContainerNode nodeRecord = this.current.Parent;
//删除
this.current = null;
GC.Collect();//回收!
//还原
this.current = nodeRecord;//
}
}
//册除对象的子节点
public bool DeleteChildrens()
{
if (this.current.Childrens == null)
{
return false;
}
else
{
//不知这样是否会有内存泄漏,因为他的字节点可能来用字节点!
this.current.Childrens == null;
GC.Collect();
return true;
}
}
///改
public bool AlterCurrentData(object data)
{
//正常情况下,不会执行下面的代码
if (this.current == null)
{
return false;
}
//
this.current.Data = null;
GC.Collect();
this.current.Data = data;
return true;
}
///查
//查当前指针指向的数据
public object GetCurrentData()
{
if (this.current == null)
{
return null;
}
return this.current.Data;
}
//查当前字节点的数据
public List<object> GetChildrenData()
{
if (this.current.Childrens == null || this.current.Childrens.Count <= 0)
{
return null;
}
else
{
List<object> data = new List<object>();
foreach (TreeContainerNode node in this.current.Childrens)
{
data.Add(node.Data);
}
return data;
}
}
}
c#objectlist数据结构

解决方案 »

  1.   

    this.current = null;
    GC.Collect();//回收!
    这2行多余,直接将当前节点修改即可,无需指向null,更不用GC来回收,影响效率的。
    .NET除非引用存在,或者使用了托管资源,否则不可能内存泄漏,只要对象引用没了(没有变量指向它),就肯定会被回收的。
      

  2.   

    .NET除非引用存在,或者使用了托管资源
    修正下:
    .NET除非引用存在,或者使用了托管资源
      

  3.   

    请问 二楼的大侠,
    是这样的,  
     因为 我删除的时候,是删除当前的节点对象,当节点对象里可能包含着他的子节点对象,
    他的子节点对象可能包含着他的孙节点对象,
      我就让当前节点对象指向null 是不是就可以让他的子子孙孙都销毁呢? //不过,还有我发现了一个错误, 
       就是这个类 TreeContainer 的 DeleteCurrentNode 方法,没有让他的parent节点对他引用的变量设为空, (忘记了
       这个失误. 是不是会造成 ,节点始终删除不掉,而内存卸漏呢?
      

  4.   

    然后我查了一下: 就把
      DeleteCurrentNode 方法改成下面的。就万事大吉了?//删除当前节点
    public bool DeleteCurrentNode()
    {
    //没有父节点 当前节点就是根节点
    //不能删除跟节点
    //要删除,可以销毁本对象
    if (this.current.Parent == null)
    {
    return false;
    }
    else
    {
    //删除并移到父节点
    //记录
    TreeContainerNode nodeRecord = this.current.Parent;
    //删除 --把 父节点 对此对象的引用 打断
    for (int i = 0;i<this.current.Parent.Childrens.Count;i++)// eachChildrenNode in this.current.Parent.Childrens)

    //他的父节点的子节点集合中的一个 是不是引用了我要删除的对象?
    if (Object.ReferenceEquals(this.current.Parent.Childrens[i], this.current))
    {
    this.current.Parent.Childrens.RemoveAt(i);
    }
    }
    //this.current = null;
    //GC.Collect();//回收!
    //还原
    this.current = nodeRecord;//
    }
    }还有一个问题!
       现在我有一个引用, 他指向[对象A]
       对于[对象A]来说,可能在其它地方, 还有其它引用指向他,问题,是我不知道在哪里还有引用指向[对象A]
     现在,我想删除对象A ,并回收他的内存, 因为暂时用不到,等用到了再重新加载!
      (假如 此对象特大,例如他存放的是图片类型的数据--一些图片变换后的数据)请问:
       这该怎么办?
      

  5.   

    即使节点再多嵌套,将根节点引用去掉,就全部释放了,这就好比你释放某个对象的引用但不需要考虑对象属性,也许对象属性也包含其它引用呢?
    但是图片是非托管资源,MSDN上面明确写明了必须调用Dispose并将变量指向null才行,因此如果节点包含了图片,则必须对每个节点的图片对象调用Dispose才行,至于指向null可以不必,因为节点对象本身无引用了,自然会被释放,那么图片对象也会被指向null。
      

  6.   

    可以这么办,自定义类的时候,继承IDispose接口,重写Dispose方法,里面对内部的图片对象Dispose下,这样当这个自定义的类对象无任何引用时,系统就会在某个时刻(内存不足或空闲时或GC强制回收时),回收这个对象,回收时自动调用你重写的Dispose方法,进而释放图片对象,保证了非托管资源的准确释放。由于这个“无任何引用时”是系统来判断的,因此你不需要考虑“对于[对象A]来说,可能在其它地方, 还有其它引用指向他”