在C#中,当你看到一个引用类型的东西(即用类而不是struct声明的类型)时,你基本上总是通过一个指针来处理对象。在C中,默认情况下,一切都是一个值类型,而在C#中,默认情况下,一切都是一个引用类型。
当你在C#参数列表中说“ref”时,你真正说的更像是一个“指针指针”。你说的是,在方法中,你要替换的不是对象的内容,而是对对象本身的引用,在代码中调用你的方法。
除非这是你的意图,那么你应该直接传递引用类型;在C#中,传递引用类型很便宜(类似于在C中传递引用)。
学习/了解C#中的值类型和引用类型之间的差异。它们是该语言中的一个主要概念,如果您尝试在C#领域中使用C对象模型,则事情会变得非常混乱。
以下是基本上语义相当的程序:
#include
class AClass
{
int anInteger;
public:
AClass(int integer)
: anInteger(integer)
{ }
int GetInteger() const
{
return anInteger;
}
void SetInteger(int toSet)
{
anInteger = toSet;
}
};
struct StaticFunctions
{
// C# doesn't have free functions, so I'll do similar in C++
// Note that in real code you'd use a free function for this.
static void FunctionTakingAReference(AClass *item)
{
item->SetInteger(4);
}
static void FunctionTakingAReferenceToAReference(AClass **item)
{
*item = new AClass(1729);
}
};
int main()
{
AClass* instanceOne = new AClass(6);
StaticFunctions::FunctionTakingAReference(instanceOne);
std::cout << instanceOne->GetInteger() << "\n";
AClass* instanceTwo;
StaticFunctions::FunctionTakingAReferenceToAReference(&instanceTwo);
// Note that operator& behaves similar to the C# keyword "ref" at the call site.
std::cout << instanceTwo->GetInteger() << "\n";
// (Of course in real C++ you're using std::shared_ptr and std::unique_ptr instead,
// right? :) )
delete instanceOne;
delete instanceTwo;
}
而对于C#:
using System;
internal class AClass
{
public AClass(int integer)
: Integer(integer)
{ }
int Integer { get; set; }
}
internal static class StaticFunctions
{
public static void FunctionTakingAReference(AClass item)
{
item.Integer = 4;
}
public static void FunctionTakingAReferenceToAReference(ref AClass item)
{
item = new AClass(1729);
}
}
public static class Program
{
public static void main()
{
AClass instanceOne = new AClass(6);
StaticFunctions.FunctionTakingAReference(instanceOne);
Console.WriteLine(instanceOne.Integer);
AClass instanceTwo = new AClass(1234); // C# forces me to assign this before
// it can be passed. Use "out" instead of
// "ref" and that requirement goes away.
StaticFunctions.FunctionTakingAReferenceToAReference(ref instanceTwo);
Console.WriteLine(instanceTwo.Integer);
}
}