问题描述
我正在使用ref
,但不清楚地理解它像C/C ++中的指针一样,还是像C ++中的引用一样?"
I'm working with the ref
and don't understand clearly "Is it like a pointer as in C/C++ or it's like a reference in C++?"
为什么我问了你一会儿这么弱的问题?因为,当我阅读C#/.NET书籍,msdn或与C#开发人员交谈时,由于以下原因,我感到困惑:
Why did I ask such a weak question as you thought for a moment?Because, when I'm reading C#/.NET books, msdn or talking to C# developers I'm becoming confused by the following reasons:
- C#开发人员建议不要在函数的参数中使用
ref
,e.g. ...(ref Type someObject)
不会对他们有好处,他们建议...(Type someObject)
,我真的不太清楚这个建议.我听到的原因:更好地使用对象的副本,然后将其用作返回值,而不是通过引用破坏内存等.通常,我会听到有关DB连接对象的此类解释.像我平常的C/C ++经验一样,我真的不明白为什么在C#中使用引用是不好的事情?我控制对象的寿命及其内存分配/重新分配等...我在书籍和论坛上阅读的内容仅建议it's bad, because you can corrupt your connection and cause a memory leak by a reference lose
,因此我控制了对象的寿命,我可能手动控制了我真正想要的东西,所以为什么是不好吗? - 如今阅读不同的书籍并与不同的人交谈,我不清楚是
ref
是指针(*
)还是&
在C ++中的引用?我记得C/C ++中的指针总是分配大小为void*
类型的空间-4个字节(有效大小取决于体系结构),在该空间中托管结构或变量的地址.在C ++中,通过传递引用&
,没有来自堆/堆栈的新分配,并且您已经在内存空间中使用了已定义的对象,并且没有像普通C那样从外部为指针进行子分配的内存.所以在C#中? .NET VM是否像普通C/C ++中的指针一样处理它,并且它的GC
为指针分配临时空间,还是像C ++中的引用一样工作?ref
是否仅正确使用托管类型或对于bool, int
之类的值类型,最好切换unsafe
代码并以非托管样式传递指针?
- C# developers suggest NOT to use
ref
in the arguments of a function,e.g. ...(ref Type someObject)
doesn't smell good for them and they suggest...(Type someObject)
, I really don't understand clearly this suggestion. The reasons I heard: better to work with the copy of object, then use it as a return value, not to corrupt memory by a reference etc... Often I hear such explanation about DB connection objects. As on my plain C/C++ experience, I really don't understand why to use a reference is a bad stuff in C#? I control the life of object and its memory allocations/re-allocations etc... I read in books and forums only advisesit's bad, because you can corrupt your connection and cause a memory leak by a reference lose
, so I control the life of object, I may control manually what I really want, so why is it bad? - Nowadays reading different books and talk to different people, I don't clearly understand is
ref
a pointer (*
) or a reference like in C++ by&
? As I remember pointers in C/C++ always do allocate a space with a size ofvoid*
type - 4 bytes (the valid size depends on architecture), where hosts an address to a structure or variable. In C++ by passing a reference&
there is no new allocations from the heap/stack and you work with already defined objects in memory space and there is no sub-allocating memory for a pointer externally like in plain C. So what's theref
in C#? Does .NET VM handle it like a pointer in plain C/C++ and itsGC
allocates temporary space for a pointer or it does a work like reference in C++? Doesref
work only with a managed types correctly or for value types likebool, int
it's better to switch anunsafe
code and pass through a pointer in unmanaged style?
推荐答案
在C#中,当看到引用引用类型的内容(即用class
而不是struct
声明的类型)时,您将本质上,总是通过指针处理对象.在C ++中,默认情况下,所有内容都是值类型,而在C#中,默认情况下,所有内容都是引用类型.
In C#, when you see something referring to a reference type (that is, a type declared with class
instead of struct
), then you're essentially always dealing with the object through a pointer. In C++, everything is a value type by default, whereas in C# everything is a reference type by default.
在C#参数列表中说"ref"时,您实际上所说的更像是指向指针的指针".您说的是,在方法中,您不想在调用方法的代码中替换对象的内容,而是替换对象本身的引用.
When you say "ref" in the C# parameter list, what you're really saying is more like a "pointer to a pointer." You're saying that, in the method, that you want to replace not the contents of the object, but the reference to the object itself, in the code calling your method.
除非您的意图是,否则您应该直接传递引用类型;否则,您应该直接传递引用类型.在C#中,传递引用类型很便宜(类似于在C ++中传递引用).
Unless that is your intent, then you should just pass the reference type directly; in C#, passing reference types around is cheap (akin to passing a reference in C++).
了解/理解C#中的值类型和引用类型之间的区别.它们是该语言的主要概念,如果您尝试考虑在C#领域中使用C ++对象模型,事情将变得非常混乱.
Learn/understand the difference between value types and reference types in C#. They're a major concept in that language and things are going to be really confusing if you try to think using the C++ object model in C# land.
以下是在语义上等效的程序:
The following are essentially semantically equivalent programs:
#include <iostream>
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);
}
}
这篇关于C#ref是C/C ++中的指针还是C ++中的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!