我主要使用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)
这是一个正确的比喻吗?
答案 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 x
与object *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
阻止您的代码。