【问题标题】:Does this copy the reference or the object?这会复制引用还是对象?
【发布时间】:2010-06-16 16:46:27
【问题描述】:

对不起,我既厚又懒,但主要是懒惰。实际上,甚至不是这样。我正在努力节省时间,以便我可以在更短的时间内做更多的事情,因为还有很多事情要做。

这是复制引用还是实际的对象数据?

public class Foo
{
    private NameValueCollection _nvc = null;

    public Foo( NameValueCollection nvc)
    {
        _nvc = nvc;
    }
}

public class Bar
{
    public static void Main()
    {
        NameValueCollection toPass = new NameValueCollection();
        new Foo( toPass ); // I believe this only copies the reference
                           // so if I ever wanted to compare toPass and 
                           // Foo._nvc (assuming I got hold of the private 
                           // field using reflection), I would only have to
                           // compare the references and wouldn't have to compare
                           // each string (deep copy compare), right?
}

我想我肯定知道答案:它只复制参考。但我什至不确定我为什么要问这个。

我想我唯一关心的是,如果在通过使用toPass 调用其参数化ctor 来实例化Foo 之后,我是否需要确保我以toPass 传递的NVC 和NVC 私有字段_nvc内容完全一样,我只需要比较他们的引用,对吧?

【问题讨论】:

  • 请记住,如果您说new Foo(toPass),然后将toPass 指向另一个对象(无论是新实例还是现有实例),那么foo 中的_nvc 将不再引用到与toPass 相同的对象。引用相等将不再有用(除非这是您的唯一考虑因素)。
  • 谢谢,安东尼。我明白那个。是的,我只需要在new Foo(toPass) 之后立即进行参考检查,然后取消 toPass。

标签: c# oop object namevaluecollection


【解决方案1】:

是的,没错。但是,如果您想稍后比较 toPassFoo._nvc,您仍然可能需要进行成员比较,以便不同但等效的集合比较相等。

【讨论】:

  • 谢谢,马修。 toPass 和 newing Foo 的操作将是一次性的,我的等效比较也必须是一次性的,所以我不必处理你描述的情况,但你确实使一个非常有趣的观点。
【解决方案2】:

总之,是的。

【讨论】:

    【解决方案3】:

    您正在按值传递引用类型。您可以更改引用指向的数据(例如,将新项目添加到集合中)并且更改将反映给调用者。正如 Matthew 指出的,您可能仍需要检查不同但等效的对象。

    假设您坚持打印的用法并且不执行任何“新”操作,则对象引用将保持等效。

    public class Foo 
        { 
            public NameValueCollection _nvc = null;
    
            public Foo( NameValueCollection nvc) 
            {
                //this is cool
                _nvc = nvc;
                _nvc.Add("updated", "content");
    
                //this isn't cool. Now you have a new object with equivalent members and you should follow Matthew's advice
                //_nvc = new NameValueCollection();
                //_nvc.Add("foo", "bar");
                //_nvc.Add("updated", "content");
            } 
        }
    
        public class Bar
        {
            public static void Main()
            {
                NameValueCollection toPass = new NameValueCollection();
                toPass.Add("foo", "bar");
                Foo f = new Foo(toPass); 
    
                if (Object.Equals(toPass, f._nvc))
                    Console.WriteLine("true");
                else
                    Console.WriteLine("false");
                Console.ReadLine();
            }
        }
    

    【讨论】:

    • 感谢您的简短教程。它加强了我对主题的理解。
    【解决方案4】:

    编辑:是的,这复制了引用的值。

    我也同意 Matthew Flaschen 关于深度复制比较的观点 - 并且还重载了您的相等比较运算符

    【讨论】:

    • 不是 ByRef。与此等效的 C# 是 ref 关键字。如果它ref,则构造函数可能会影响MaintoPass的值。
    • 当他执行“new Foo(toPass)”时,他不是将 obj 的引用向下发送以复制到“_nvc”吗?这不就是为什么当他比较这两个变量时会得出相等的结果吗?我错过了什么?
    • 他正在传递引用的。同样,VB.NET ByRef 是 C# 参考。
    猜你喜欢
    • 2012-04-19
    • 2019-12-06
    • 1970-01-01
    • 2012-02-24
    • 2021-02-05
    • 2015-01-11
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    相关资源
    最近更新 更多