2009-06-26 6 views
7

私は文字列が不変であることを知っているので、文字列参照の値を変更すると、.NETは新しい文字列をヒープ上に作成します。VB.NET:関数にString ByValを渡しても文字列を変更しないと、メモリに1つまたは2つの文字列がありますか?

を変更しないと、の文字列参照の値が変更されます。代わりに、単に関数に渡すだけです。ByVal - この操作では、文字列値もヒープにコピーされますか?私の傾向は「いいえ」ですが、確認したいと思います。例えば

Public Function IsStringHello(ByVal test As String) As Boolean 
    Return (String.Compare(test, "Hello") = 0)  
End Function 

はプログラムの呼び出し:私は知っている

Dim myWord as String = "Blah" 
Dim matchesHello as Boolean = IsStringHello(myWord) 

を値でmyWordを渡すと、「何とか」に参照のコピーを作成しますが、私は試していないので、文字列自体を変更すると、ヒープに文字列の別のコピーが作成されますか?

+0

なぜ人々はこの奇妙な方法で文字列を比較するのですか?http://stackoverflow.com/questions/859005/string-comparison-performance/859078 – Dario

+1

String.Compareを使用すると、大文字と小文字の区別を指定できます。これを比較する前に、文字列を大文字にするよりはっきりしているかもしれません。 –

答えて

9

ところで、文字列インターンは完全にそれに無関係です。パラメータを関数に渡すルールは、内部的にどのように管理されているかにかかわらず、すべての参照型(実際にはすべての型)で同じです。

ルールは簡単で、あなたはそれを正しく述べている:値をコピーによって参照、ないターゲットを渡します。ヒープスペースはここにコピーされません。

+0

インターンは直接関連していません。あなたは言った:ルールは、内部で管理されているかどうかに関係なく、すべての参照型(実際には、すべての型)で同じです - 私はあなたが参照のコピー&インターナショナルではないと思う。右? – shahkalpesh

+0

ああ。私は声明を明確にした。 –

4

いいえ、まだののコピーを "Blah"に使用しています。
あなたはどう思いますか?

サイドノートでは、文字列は使用できません。

string s = "hello"; 
string t = "hello"; 

S & T(それはインターンされているため)の両方が、同じ文字列を指します。 sまたはtを変更すると、新しい文字列が作成されます。

+0

不変なオブジェクトへの参照のコピーを作成するだけで、オブジェクトそのもののコピーが作成されたという奇妙な(愚かな)考えがありました。私はこれが事実ではないと強く疑ったが、私は確認したかった。文字列の「インターン」についての大きな副作用 - 私はそれを知らなかった。ありがとう! –

+0

文字列*定数*は使用できません。他の方法で作成する文字列は、インターンされません。 –

+0

@JonSkeet - ああ... shahkalpeshの答えでは、同じ文字列に2つの参照を割り当てる*リテラル*は、ヒープ上の同じ文字列を参照しているわけではありませんか? –

0

短くてもいいですか。それは文字列にrefを渡します。文字列自体のインスタンスは1つだけです。

0

文字列は参照型です。値渡しを渡すと、渡しているのは参照の値です。

ヒープ上に別のコピーを作成する唯一の方法は、変数の値を変更することです。

2

オブジェクトを渡すByValオブジェクトのポインタのコピーを作成します。ここではデモンストレーションです:

Module Module1 
    Dim original As String = "Hello world" 

    Sub PassByReferenceTest(ByVal other As String) 
     Console.WriteLine("object.ReferenceEquals(original, other): {0}", _ 
      Object.ReferenceEquals(original, other)) 
    End Sub 

    Sub Main() 
     PassByReferenceTest(original) 
     Console.ReadKey(True) 
    End Sub 
End Module 

このプログラムは次のように出力します

object.ReferenceEquals(original, other): True 

ので、元の文字列と、我々は値によって渡された文字列は、メモリアドレス内の同じアドレスに存在します。文字列自体のコピーを作成していません。

0

タイプSystem.Stringの変数は事実上「オブジェクトID」を保持します。Object #1934は、文字が"Blah"で、文字列がDim myWord As String = "Blah"とするとします。コンパイラはObject #1934myWordに格納します。 IsStringHello(myWord)を呼び出すと、testパラメータがObject #1934に等しい関数が呼び出されます。あなたの例では、myWordtestの2種類の変数System.Stringがあり、両方とも内容がObject #1934になります。

関連する問題