Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.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#_Ref - Fatal编程技术网

C# '的内部工作;参考';具有指向同一地址的两个对象的关键字

C# '的内部工作;参考';具有指向同一地址的两个对象的关键字,c#,ref,C#,Ref,看看下面的代码,告诉我为什么在调用函数UpdateContext之后,变量connection2没有与变量connection1相同的hashcode 当我将变量connection2设置为connection1时,两个变量都有一个指向相同内存地址的指针。但是在函数UpdateContext中通过ref传递变量connection1,该函数使用“new”指令修改指针后,connection1有一个新的指针地址,但connection2仍然使用旧地址 class Program {

看看下面的代码,告诉我为什么在调用函数UpdateContext之后,变量connection2没有与变量connection1相同的hashcode

当我将变量connection2设置为connection1时,两个变量都有一个指向相同内存地址的指针。但是在函数UpdateContext中通过ref传递变量connection1,该函数使用“new”指令修改指针后,connection1有一个新的指针地址,但connection2仍然使用旧地址

   class Program
   {
      static void Main(string[] args)
      {
         var connectionInitializer = new ConnectionInitializer();

         connectionInitializer.Initialize();

         Console.ReadLine();
      }
   }

   public class Connection
   {

   }

   public class ConnectionInitializer
   {
      public void Initialize()
      {
         var connection1 = new Connection();
         var connection2 = connection1;

         Console.WriteLine("Connection 1 (Before ref): " + connection1.GetHashCode());
         Console.WriteLine("Connection 2 (Before ref): " + connection2.GetHashCode());

         this.UpdateContext(ref connection1);

         Console.WriteLine("Connection 1 (After ref): " + connection1.GetHashCode());
         Console.WriteLine("Connection 2 (After ref): " + connection2.GetHashCode());
      }

      private void UpdateContext(ref Connection connection)
      {
         connection = new Connection();
      }
   }

谢谢您的帮助。

您似乎误解了
ref
的目的。基本上,当您将变量作为
ref
参数传递时,它允许被调用者修改(原始)变量的值,就像它是本地变量一样。既然如此,为什么您希望覆盖变量
connection1
的值也会更改分配给
connection2
的值

换句话说,使用
ref
类似于此代码:

var connection1 = new Connection();
var connection2 = connection1;
connection1 = new Connection()

显然,在这种情况下,
connection2
应该保持不变。您的也是如此。

当您初始化连接对象时,它会分配新的内存,从而分配新的哈希代码

connection2
仍然引用原始的
连接
对象<代码>连接1已修改为引用新的
连接
对象<代码>连接1和
连接2
不是字面上相同的参考
connection2
connection1
的副本,并且这两个引用在一段时间内都引用了同一个对象


这两个参考文献之间没有任何有意义的联系,除了它们所指的以外,一个只是另一个的副本。更改原稿不会反映拷贝。

< P>如果你讲C++,引用和输出实际上只是指针,你传递的标识符通过的地址。与之相比:

void foo(int** p);

int main()
{
  int* one = new int(4);
  int* two = one;

  cout << "one|two before: " << *one << "|" << *two << endl;

  foo(&one);

  cout << "one|two after: " << *one << "|" << *two << endl;

  return 0;
}

void foo(int** p)
{
  *p = new int(5);
}

<强>注<>强>我可以使用C++ ReF传递,但是在引擎盖下,这些都只是指针。

Kirk Woll的回答是正确的,我认为当他说你误解了<代码> REF> /Cord>关键字时,他忽略了一点。这种误解很常见,但更多的是对引用类型本身性质的误解

Kirk的解释(“使用ref类似于此代码”)实际上反映了我记得的其他SO问题,例如“为什么下面的示例不打印<代码>再见?”

(很抱歉,找不到实际问题的链接。)

如果您记住引用类型变量存储对引用类型实例的引用,而值类型变量直接存储值类型的实例,则更容易跟踪

我发现这是一种比通常的“引用类型按引用传递;值类型按值传递”更好的思考方式。事实上,引用类型变量(缺少
ref
out
)按值传递,但值本身就是一个引用。那太令人困惑了。更不容易混淆的是:“引用类型变量包含对该类型实例的引用”


当然,
ref
关键字在某种程度上使这变得复杂,因为ref参数包含对变量的引用。这意味着引用类型
ref
参数存储对该类型实例引用的引用。同样,如果您考虑到引用类型变量包含引用这一事实,那么您可以停在包含变量引用的ref参数处。这比“引用到…的引用”更容易推理。

您正在逐个引用传递引用类型,因此这是预期的行为。您将connection1引用指向UpdateContext中的新对象,但connection2当然仍将指向旧对象。非常感谢。我不知道为什么我会这样想,当你将一个变量设置为同一个地址到另一个地址时,即使你将地址更改为一个或另一个,两个变量也共享同一个地址。这实际上不是“ref”关键字的问题,而是我对@KirkWoll的误解。把一些变量放到同一个地址不是我在应用程序中经常做的任务。再次感谢您抽出时间。
one|two before: 4|4
one|two after: 5|4
string a = "Hello";
string b = a;
a = "Goodbye";
Console.WriteLine(b);