与C ++相比,使用C#'ref'关键字

时间:2012-08-13 13:23:40

标签: c# c++

我主要使用C ++,现在我在新工作中使用C#,在这里阅读了关于'ref'关键字和c#值与引用类型的内容之后,我仍然发现它们与它们有些混淆。

据我了解这些,如果你将这些传递给方法,这些将是类似的C ++样式:

价值类型:

public void CSharpFunc(value)

public void CPlusplusFunc(value)

参考类型:

public void CSharpFunc(reference)

public void CPlusPlusFunc(&reference)

'ref'/指针

public void CSharpFunc(ref bar)

public void CPlusPlus(*bar)

这是一个正确的比喻吗?

3 个答案:

答案 0 :(得分:12)

  

这是一个正确的比喻吗?

尽管其他答案说的是,不。 ref在C ++方面的含义实际上取决于类型。对于值类型,您的评估是正确的(或足够接近)。对于引用类型,更合适的类比是指向引用:

public void CPlusPlus(type*& bar)

关于ref的重点是你可以更改传入的引用。你不能通过简单地传递一个指针在C ++中这样做:

void f(type* bar) {
    bar = new_address;
}

type* x;
f(x);

此代码不会更改来电者x的值。如果您已将bar作为type*&传递,另一方面,更改该值。这就是ref的作用。

此外,C#中的引用与C ++中的引用完全不同,更像是C ++中的指针(因为您可以更改引用引用的对象)。

答案 1 :(得分:3)

交换“参考类型”和“ref”示例会更准确(但仍然不是完全相同)。

在C#中,引用类型是一种始终通过对类型实例的引用在内部访问的类型。这些作为C ++意义上的“指针”是最简单的:你分配内存,运行构造函数,并获取一个间接引用你想要的对象的值。 C#和C ++之间的区别在于,在C#中,这是类型的属性,而不是变量的属性。类型是始终引用类型或始终值类型。这样做的一个结果是你不必做任何特殊的事情来使用引用类型(托管C#代码中没有“dereference”操作符);编译器假定引用类型变量访问是间接的。在C ++中,您仍然需要使用->运算符,因为您可以同时使用相同类型的值和引用变量(object xobject *x)。

ref关键字用于通过引用传递参数;这些参数可以是值类型(如int)或引用类型。虽然ref关键字的实现最终是一个地址/指针到类型的操作(正如&在C ++中),ref(和out)生成一种称为 托管引用 的特殊类型的对象,它与引用类型的不同之处在于您可以对值类型进行托管引用。这几乎就是C ++的工作方式:int&是一种特殊类型的“对int的引用”,它与int *不同,即使两者基本上都是使用指针间接访问变量。同样,在C#中,您可以拥有ref Object,这实际上是object *&

答案 2 :(得分:1)

是的,你大多是正确的,(s / * / *&你在那里是100%)。正如@weston所提到的,out是一个值得熟悉的附加关键字。你可以用ref做的唯一可爱的事情是重载一个不是参考的函数。

class Person {
   string Name { get; set; }
   string Address { get; set; }
   int age { get; set; }
}

public void UpdateName(Person p)
{
   if (p == null) 
   {
      return;
   }

   p.Name = "Tom";
}

public void UpdateName(ref Person p)
{
   if (p == null)
   {
      p = new Person();
   }

   p.Name = "Tom";
}

显然没用,但确实提供了一些有趣的机会(和糟糕的设计)。 out不提供相同的重载功能。

如果您希望1对1,则始终可以使用unsafe阻止您的代码。