Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么有时两个对象引用相同的对象,但并不总是如此_C#_Reference_Referenceequals - Fatal编程技术网

C# 为什么有时两个对象引用相同的对象,但并不总是如此

C# 为什么有时两个对象引用相同的对象,但并不总是如此,c#,reference,referenceequals,C#,Reference,Referenceequals,最后一个答案如下: 我想使用与CreateTree相同的方法,但与Hierarchy以外的另一个对象:ItemNode: public class ItemNode { public string Id { get; set; } public Item Item { get; set; } public ICollection<ItemNode> Children { get; set; } } static List<ItemNode>

最后一个答案如下:

我想使用与CreateTree相同的方法,但与Hierarchy以外的另一个对象:ItemNode:

public class ItemNode
{
    public string Id { get; set; }
    public Item Item { get; set; }
    public ICollection<ItemNode> Children { get; set; }
}
    static List<ItemNode> CreateTreeItems(IEnumerable<ItemNode> nodes)
    {
        Dictionary<string,ItemNode> idToNode = nodes.ToDictionary(n => n.Id, n => n);
        List<ItemNode> roots = new List<ItemNode>();
        ItemNode root = null;

        foreach (var n in nodes)
        {
            if (n.Item.ParentId == null)
            {
                if (root != null)
                {
                    roots.Add(root);
                }
                root = n;
                continue;
            }

            ItemNode parent = idToNode[n.Item.ParentId];
            //if (!idToNode.TryGetValue(n.Item.ParentId, out parent))
            //{
            //  //Parent doesn't exist, orphaned entry
            //}

            parent?.Children.Add(n);

            // RETURNS FALSE WHEREAS IN THE ORIGINAL METHOD IT RETURNS TRUE
            var test = Object.ReferenceEquals(parent, root);
            Debug.WriteLine(test);
        }


        if (root == null)
        {
            //There was no root element
        }

        roots.Add(root);
        return roots;
    }
下面是带有ItemNode的CreateTree方法:

public class ItemNode
{
    public string Id { get; set; }
    public Item Item { get; set; }
    public ICollection<ItemNode> Children { get; set; }
}
    static List<ItemNode> CreateTreeItems(IEnumerable<ItemNode> nodes)
    {
        Dictionary<string,ItemNode> idToNode = nodes.ToDictionary(n => n.Id, n => n);
        List<ItemNode> roots = new List<ItemNode>();
        ItemNode root = null;

        foreach (var n in nodes)
        {
            if (n.Item.ParentId == null)
            {
                if (root != null)
                {
                    roots.Add(root);
                }
                root = n;
                continue;
            }

            ItemNode parent = idToNode[n.Item.ParentId];
            //if (!idToNode.TryGetValue(n.Item.ParentId, out parent))
            //{
            //  //Parent doesn't exist, orphaned entry
            //}

            parent?.Children.Add(n);

            // RETURNS FALSE WHEREAS IN THE ORIGINAL METHOD IT RETURNS TRUE
            var test = Object.ReferenceEquals(parent, root);
            Debug.WriteLine(test);
        }


        if (root == null)
        {
            //There was no root element
        }

        roots.Add(root);
        return roots;
    }
静态列表CreateTreeItems(IEnumerable节点)
{
Dictionary idToNode=nodes.ToDictionary(n=>n.Id,n=>n);
列表根=新列表();
itemnoderoot=null;
foreach(节点中的变量n)
{
if(n.Item.ParentId==null)
{
if(root!=null)
{
根。添加(根);
}
根=n;
继续;
}
ItemNode parent=idToNode[n.Item.ParentId];
//if(!idToNode.TryGetValue(n.Item.ParentId,out parent))
//{
////父项不存在,孤立项
//}
父项?.Children.Add(n);
//返回FALSE,而在原始方法中返回TRUE
var test=Object.ReferenceEquals(父、根);
调试写线(测试);
}
if(root==null)
{
//没有根元素
}
根。添加(根);
回归根;
}
它不起作用,因为父对象和根对象不引用相同的对象(而在原始方法中,它引用相同的对象)。我猜这与我在ItemNode类中添加了一个Item属性有关。但我不知道如何修复它


谢谢大家!

为什么希望根节点引用和父节点引用相等?每个根节点都可能是父节点,但并非每个父节点都是根节点

可能存在引用相等的情况,但这非常取决于
节点
集合的排序顺序。实际上,当根节点放置在第一级子节点之前时,您将看到引用相等的情况

我假设您的问题在其他地方,例如,如果
节点
集合根本没有根节点,那么它可能不起作用

这是一个例子,在这里试试

使用系统;
使用System.Collections.Generic;
使用System.Linq;
公共类层次结构
{
公共层次结构(字符串iD、字符串名称、int级别、字符串parentID、字符串topParent)
{
ID=ID;
名称=名称;
级别=级别;
ParentID=ParentID;
Children=newhashset();
}
公共字符串ID{get;set;}
公共字符串名称{get;set;}
公共整数级别{get;set;}
公共字符串ParentID{get;set;}
公共ICollection子项{get;set;}
}
公共课程
{
静态层次结构CreateTree(IEnumerable节点)
{
var idToNode=Nodes.ToDictionary(n=>n.ID,n=>n);
层次根=空;
foreach(节点中的变量n)
{
如果(n.ParentID==null)
{
if(root!=null)
{
//数据中有多个根
}
根=n;
继续;
}
层次结构parent=null;
if(!idToNode.TryGetValue(n.ParentID,out parent))
{
//父项不存在,孤立项
}
parent.Children.Add(n);
WriteLine(“ReferenceEquals:{0}”,Object.ReferenceEquals(父,根));
}
if(root==null)
{
//没有根元素
}
返回根;
}
公共静态void Main()
{
控制台写入线(“测试1”);
列表l=新列表();

l、 添加(新的层次结构(“295152”,“name1”,1,null,null));//您需要修复什么?对象只对自身进行
ReferenceEquals
。是的,它可以与Hierarchy类配合使用。但是当我想用ItemNode替换层次结构时,它就不再起作用了。我怀疑这是因为父变量和根变量没有引用同一个对象,而它们使用hiera引用同一个对象rchy object:@Florian好的,现在我明白了。你已经成为LINQ懒惰的受害者。要查看它创建
ItemNode
对象的频率,请将
Select
块替换到下一个:
var rawItems=GetItems()。选择(c=>{Console.WriteLine(“创建节点:{0}”,c.ID);返回新的ItemNode{Id=c.Id,Item=c,Children=new List()};})
。在您的示例中,
idToNode
dictionary和
nodes
collection包含不同的对象。@Florian通常,您的问题可以通过简单地更改对
var test=CreateTreeItems(rawtItems.ToList())的调用来解决是的,你说得对!谢谢!!!当我使用你的块时,我看到“创建节点:295152”和“创建节点:12345”两行。我在哪里使用.ToList()扩展方法。那些重复的行不再出现。但是你知道为什么吗?顺便说一句,再次感谢你!这都是因为LINQ延迟执行。请仔细查看这里。当你使用
ToList()时
-您正在将一个完整的集合传递到
CreateTreeItems
方法中。但是,如果您不这样做,该方法将接收可能生成集合的命令链。
ToDictionary
foreach
都执行该命令链,并最终得到两个不同的集合。