VB.NET: إذا قمت بتمرير سلسلة Byval في وظيفة ولكن لا تغير السلسلة ، هل لدي سلسلتين أو سلسلتين في الذاكرة؟

StackOverflow https://stackoverflow.com/questions/1050590

  •  20-08-2019
  •  | 
  •  

سؤال

أعلم أن الأوتار غير قابلة للتغيير ، لذا في اللحظة التي تقوم فيها بتغيير قيمة مرجع السلسلة. NET تجعل سلسلة جديدة على الكومة.

لكن ماذا لو لم تفعل يتغيرون قيمة مرجع السلسلة ؛ بدلا من ذلك ، يمكنك ببساطة تمريرها إلى وظيفة 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 بالقيمة تجعل نسخة من المرجعي إلى "بلاه" ، لكن بما أنني لم أحاول تغيير السلسلة نفسها ، فهل ستجعل نسخة أخرى من السلسلة على الكومة؟

هل كانت مفيدة؟

المحلول

بالمناسبة ، لا علاقة لها بالتداخل تمامًا. قاعدة تمرير المعلمات إلى الوظائف هي نفسها بالنسبة لجميع أنواع المرجع (وحقا ، جميع الأنواع) ، بغض النظر عن كيفية إدارتها داخليًا.

القاعدة بسيطة وقد ذكرت ذلك بشكل صحيح: تمرير بنسخ القيمة المرجعي, ، ليس استهداف. لا يتم نسخ مساحة كومة هنا.

نصائح أخرى

لا. لا يزال يستخدم نسخة من المرجع إلى "بلاه".
ما الذي يجعلك تفكر ، سوف؟

على ملاحظة جانبية ، يتم تدريب السلسلة.

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

يشير S&T إلى نفس السلسلة (لأنه يتم تدريبه). إذا قمت بتعديل S أو T ، فسيقوم بإنشاء سلسلة جديدة ، ثم.

تمرير الكائنات 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

لذلك ، توجد السلسلة الأصلية والسلسلة التي مررنا بها حسب القيمة في نفس العنوان في عنوان الذاكرة. أنت لا تصنع نسخة من السلسلة نفسها.

قصير ، لا. يمرر المرجع إلى السلسلة. مثيل واحد فقط من السلسلة نفسها.

السلسلة هي نوع مرجعي. إذا قمت بتمريرها بالقيمة ، فإن ما تمر به هو قيمة المرجع.

الطريقة الوحيدة التي ستحصل على نسخة أخرى على الكومة هي تغيير قيمة المتغير.

متغير من النوع System.String يحمل بشكل فعال "معرف الكائن". لنفترض أن Object #1934 هي سلسلة مع الأحرف "Blah", ، وأنت تقول Dim myWord As String = "Blah". سيتم تخزين المترجم بعد ذلك Object #1934 داخل myWord. الدعوة IsStringHello(myWord) ثم يتسبب في استدعاء هذه الوظيفة مع test المعلمة تساوي Object #1934. في مثالك ، سيكون هناك متغيران من النوع System.String في الذاكرة--myWord و test, وكلاهما سيحمل المحتوى Object #1934.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top