如何字符串.NET通过呢?字符串、NET

2023-09-02 11:45:37 作者:慕

当我通过字符串来一个功能,是一个指向字符串的内容通过,或者是传递给函数的栈就像一个结构是?

When I pass a string to a function, is a pointer to the string's contents passed, or is the entire string passed to the function on the stack like a struct would be?

推荐答案

要回答你的问题,请考虑以下code:

To answer your question, consider the following code:

void Main()
{
    string strMain = "main";
    DoSomething(strMain);
    Console.Write(strMain); // What gets printed?
}
void DoSomething(string strLocal)
{
    strLocal = "local";
}

有三件事情你需要知道的,以predict究竟会在这里发生,并了解它为什么。

There are three things you need to know in order to predict what will happen here, and to understand why it does.

字符串是在C#中引用类型。但是,这只是问题的一部分。 他们也是不变的,所以你做的东西,看起来像你改变了字符串的时候,你是不是。被创建一个全新的字符串,引用指向它,旧的被扔掉了。 尽管字符串是引用类型, strMain 不是按引用传递。这是一个引用类型,,但引用是按值传递。这是一个棘手的区别,但它是一个关键问题。您传递参数,而不 REF 关键字(不包括退出参数)任何时候,你已经通过了一些通过值 Strings are reference types in C#. But this is only part of the picture. They are also immutable, so any time you do something that looks like you're changing the string, you aren't. A completely new string gets created, the reference is pointed at it, and the old one gets thrown away. Even though strings are reference types, strMain isn't passed by reference. It's a reference type, but the reference is being passed by value. This is a tricky distinction, but it's a crucial one. Any time you pass a parameter without the ref keyword (not counting out parameters), you've passed something by value.

但到底是什么意思呢?

But what does that mean?

有两组数据类型在C#:引用类型和值类型。此外,还有两种方法可以在C#中传递参数:引用和按值。这些声音一样,很容易混淆。他们是不一样的东西!

There are two groups of data types in C#: reference types and value types. There are also two ways to pass parameters in C#: by reference and by value. These sound the same and are easily confused. They are NOT the same thing!

如果您通过任何类型的参数,并且不使用 REF 关键字,那么你已经按值传递的。如果你按值传递它,你真的通过什么副本。但是,如果该参数是引用类型,那么你复制的东西是参考,不是不管它是指向。

If you pass a parameter of ANY type, and you don't use the ref keyword, then you've passed it by value. If you've passed it by value, what you really passed was a copy. But if the parameter was a reference type, then the thing you copied was the reference, not whatever it was pointing at.

下面是我们的方法的第一行:

Here's the first line of our Main method:

string strMain = "main";

有实际上我们已经在这条线在两件事情:一个字符串,其值离线存储在内存中的某个地方,叫一个参考变量 strMain 指向它。

There are actually two things we've created on this line: a string with the value main stored off in memory somewhere, and a reference variable called strMain pointing to it.

DoSomething(strMain);

现在我们传递了参考的DoSomething 。我们已经通过它按值,这样就意味着我们做了一个副本。但它是一个引用类型,所以这意味着我们复制了引用,而不是字符串本身。现在,我们有两个引用,每个指向存储器中的相同的值。

Now we pass that reference to DoSomething. We've passed it by value, so that means we made a copy. But it's a reference type, so that means we copied the reference, not the string itself. Now we have two references that each point to the same value in memory.

这里的的DoSomething 方法的顶部:

void DoSomething(string strLocal)

没有 REF 关键字,像往常一样。因此, strLocal 不是 strMain ,但它们都指向同一个地方。如果我们变 strLocal ,像这样...

No ref keyword, as usual. So strLocal isn't strMain, but they both point to the same place. If we "change" strLocal, like this...

strLocal = "local";   

......我们没有的修改的存储值,本身。我们再次指出的参考。我们采取了名为 strLocal 参考,目的是在一个全新的字符串。恰巧 strMain 什么,当我们做到这一点? 没有。它仍然指向旧的字符串!

...we haven't changed the stored value, per se. We've re-pointed the reference. We took the reference called strLocal and aimed it at a brand new string. What happens to strMain when we do that? Nothing. It's still pointing at the old string!

string strMain = "main"; //Store a string, create a reference to it
DoSomething(strMain);    //Reference gets copied, copy gets re-pointed
Console.Write(strMain);  //The original string is still "main" 

不变性很重要

让我们改变方案一秒钟。试想一下,我们是不是在处理字符串,但一些可变的引用类型,像一个类你已经创建。

Immutability is important

Let's change the scenario for a second. Imagine we aren't working with strings, but some mutable reference type, like a class you've created.

class MutableThing
{
    public int ChangeMe { get; set; }
}

如果您的跟踪的参考 objLocal 将其指向,可以更改其属性的对象:

If you follow the reference objLocal to the object it points to, you can change its properties:

void DoSomething(MutableThing objLocal)
{
     objLocal.ChangeMe = 0;
} 

目前仍然只有一个 MutableThing 在内存中,无论是复制的参考和原来的基准仍指向它。 的 MutableThing 本身已经改变的特性:

There's still only one MutableThing in memory, and both the copied reference and the original reference still point to it. The properties of the MutableThing itself have changed:

void Main()
{
    var objMain = new MutableThing();
    objMain.ChangeMe = 5; 
    Console.Write(objMain.ChangeMe);  //it's 5 on objMain

    DoSomething(objMain);             //now it's 0 on objLocal
    Console.Write(objMain.ChangeMe);  //it's also 0 on objMain   
}

啊,但是...

...字符串是不可变的!有没有 ChangeMe 属性来设置。你不能这样做 strLocal [3] ='H'; 像你可以用一个C风格的字符数组;你必须建立一个全新的字符串代替。只有这样,才能改变 strLocal 是指向另一个字符串参考,这意味着不管你做什么,以 strLocal 即可影响 strMain 。的值是不可变的,并且参考是一个拷贝。

Ah, but...

vb.net中从字符串 到类型 Integer 的转换无效

...strings are immutable! There's no ChangeMe property to set. You can't do strLocal[3] = 'H'; like you could with a C-style char array; you have to construct a whole new string instead. The only way to change strLocal is to point the reference at another string, and that means nothing you do to strLocal can affect strMain. The value is immutable, and the reference is a copy.

所以,即使字符串是引用类型,按值传递它们意味着什么的推移在被叫不会影响字符串中的来电。但由于他们的是的引用类型,你不必复制整个字符串在内存中,当你想身边通过。

So even though strings are reference types, passing them by value means whatever goes on in the callee won't affect the string in the caller. But since they are reference types, you don't have to copy the entire string in memory when you want to pass it around.

这是我读过关于引用类型和值类型之间的区别在C#和为什么引用类型是不一样的一个参考传递的参数。 和往常一样,埃里克利珀也有关于这个问题几个优秀的博客文章。 在他的不变性有一些伟大的东西了。 Here is the best article I've read on the difference between reference types and value types in C#, and why a reference type isn't the same as a reference-passed parameter. As usual, Eric Lippert also has several excellent blog posts on the subject. He has some great stuff on immutability, too.
 
精彩推荐
图片推荐