Benutzer mit den meisten Antworten
String ByRef vorhalten

Frage
-
Hallo alle zusammen.
Bei der Instanziierung möchte ich an eine Struktur (TStruc) den Verweis auf eine Zeichenfolgen-Eigenschaft (tProp) übergeben und in der Struktur vorhalten.
Wenn ich die Zeichenfolgen-Eigenschaft der Struktur (TStruc.Value) setze, soll diese Zeichenfolge nicht nur in der Struktur gehalten sondern auch als Wert der externen Zeichenfolgen-Eigenschaft (tProp) gespeichert werden, deren Verweis ich bei der Instanziierung übergeben hatte.
Ich hoffe, ich habe mich einigermaßen verständlich ausgedrückt.
Dazu hatte ich mir folgenden Programmcode vorgestellt:
Public Sub TSub() Dim tProp As String = "irgendetwas" Dim tStr As TStruc = New TStruc(tProp) tStr.Value = "was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp) Console.ReadLine() End Sub Public Structure TStruc Private Property _pValue As String Private Property _value As String Public Property Value As String Get Return _value End Get Set(nValue As String) _value = nValue _pValue = nValue End Set End Property Public Sub New(ByRef pValue As String) _pValue = pValue End Sub End Structure
Als Ausgabe in der Routine TSub hatte ich mir dann folgendes erhofft:
Strukturwert : was ganz anderes Eigenschaftswert : was ganz anderes
Statt dessen bekomme ich:
Strukturwert : was ganz anderes Eigenschaftswert : irgendetwas
Ich halte also nicht den Verweis auf die Eigenschaft vor.
Allerdings habe ich auch schon vielerlei versucht. Entweder bringt es nichts oder geht nicht bei "Option Strict On".
Sieht jemand meinen Denkfehler oder kann mir sonst einen verwertbaren Tipp geben?
Vielen Dank.
WM
Antworten
-
.
Dein Vorschlag funktioniert ... aber nur einmal. Jedes Mal, wenn ich tStr.Value neu zuweise, müsste ich erneut tStr.SetRef(tProp) aufrufen. Dabei wäre mir schon das erste Mal zu viel.
Das liegt daran, das Du ja die Referenz immer wieder überschreibst.
In VB.Net wird bei Strings bei der Zuweisung von Konstanten immer ein neuer Verweis gesetzt.
str1 = "Text1"
str1 = "Neuer Text"
Dabei ist es nicht so, dass str1 eine immer gleiche Referenz ist die nur den Inhalt wechselt.
Es ist tatsächlich so, das str1 zunächst auf die Konstante "Text1" verweist und dann auf "Neuer Text"
Ein Lösung Deines Problems könntest DU aber mit dem Typ Stringbuilder erreichen. Der Stringbuilder legt zunächst eine Instanz (Referenz) an, und es kann später auch nur der Inhalt verändert werden.
Nachfolgend Dein Beispiel mit Stringbuilder. Zur Verdeutlichung wird der Inhalt der Referenzvariable zweimal verändert.
Hier das Beispiel:
Public Sub TSub() Dim tProp As StringBuilder = New StringBuilder("irgendetwas") Dim tStr As TStruc = New TStruc(tProp) 'tStr.SetRef(tProp) tStr.Value = "was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp.ToString()) tStr.Value = "noch was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp.ToString()) Console.ReadLine() End Sub Public Structure TStruc Private rValue As StringBuilder Private _pValue As String Private Property _value As String Public Property Value As String Get Return _value End Get Set(ByVal nValue As String) _value = nValue _pValue = nValue rValue.Clear() rValue.Append(nValue) End Set End Property Public Sub New(ByRef pValue As StringBuilder) _value = pValue.ToString() _pValue = pValue.ToString() rValue = pValue End Sub End Structure
_pvalue wird hier nicht mehr benötigt ich habe die Variable aber nicht entfernt.
Grüße
Roland
- Bearbeitet Roland Franz Dienstag, 20. Juni 2017 17:52
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 23. Juni 2017 06:21
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 3. Juli 2017 13:19
- Tag als Antwort aufgehoben Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 3. Juli 2017 14:02
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 4. Juli 2017 06:06
Alle Antworten
-
Hallo WM,
ich bin mir nicht sicher was Du genau vor hast. Ist es eine konkrete Aufgabenstellung, oder willst Du eine Übungsaufgabe zum Zeigen des Unterschiedes zwischen Referenz- und Werttypen erstellen.
Um Dein gewünschtes Ziel zu erreichen könntest Du so vorgehen:
Public Sub TSub() Dim tProp As String = "irgendetwas" Dim tStr As TStruc = New TStruc(tProp) tStr.Value = "was ganz anderes" tStr.SetRef(tProp) Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp) Console.ReadLine() End Sub Public Structure TStruc Private _pValue As String Private Property _value As String Public Sub SetRef(ByRef RefVar As String) RefVar = _pValue End Sub Public Property Value As String Get Return _value End Get Set(ByVal nValue As String) _value = nValue _pValue = _value End Set End Property Public Sub New(ByRef pValue As String) _value = pValue End Sub End Structure
Dabei habe ich Deine Refernzvariable tProp mit einer Methode übergeben.
Grüße
Roland
- Bearbeitet Roland Franz Dienstag, 20. Juni 2017 14:51
-
Hallo Roland,
nein, es ist keine Übungsaufgabe. Es ist lediglich ein zusammengestutzer und verallgemeinerter Plan aus meiner Praxis.
Dein Vorschlag funktioniert ... aber nur einmal. Jedes Mal, wenn ich tStr.Value neu zuweise, müsste ich erneut tStr.SetRef(tProp) aufrufen. Dabei wäre mir schon das erste Mal zu viel.
Ich möchte mit der Konstruktion erreichen, dass ich mit der Struktur arbeite, aber auf die Werte auch ohne Struktur zugreifen kann. Das bedeutet, dass die für die Struktur externe Eigenschaft immer automatisch, ohne tStr.SetRef(), zugewiesen sein müsste.
Die Struktur beinhaltet eine ganze Menge zusätzlicher Eigenschaften, deren Verwaltung klappt. In der normalen Praxis kommt es aber immer nur auf den Wert an, auf den ich bspw. zugreifen möchte mit strBsp = class.Property und nicht mit strBsp = class.structure.Value. Mir wäre das noch ziemlich egal. Die Anwender kennen aber den Property-Name und werden sich schwer tun, mit .Value zu arbeiten.
Dein Vorschlag zeigt aber, dass es irgendwie gehen wird. Ich bin optimistisch und werde weiter daran arbeiten. Inzwischen bin ich dankbar für jeden weiteren Vorschlag.
Vielen Dank.
WM
-
Hi WerMil,
Dein Ansinnen ist in VB.NET nicht realisierbar, da VB.NET keine Nutzung von Pointern für Felder unterstützt. Lediglich Pointer auf Methoden können mit AddressOf Variablen vom Type Delegate zugewiesen werden.Du übergibst zwar einen Pointer (Referenz) dem Konstruktur. Mit der nachfolgenden Zuweisung wird der Inhalt geholt. Obwohl String vom Referenztyp ist, wird mit der Zuweisung aber der Inhalt analog einer Variablen vom Wertetyp übertragen. Und damit wird der Wert am ursprüngliche Ort vom Speicherort in der Struktur entkoppelt.
Um Dein Ansinnen zu realisieren, müsstest Du Dir im Konstruktor den Pointer auf die übergebene Variable merken und bei späteren Aufruf der Value-Eigenschaften diesen Pointer für Wertezuweisung nutzen. Und das lässt die CLR aus Sicherheitsgründen nicht zu.
Die einzige "Krücke", die vielleicht möglich wäre, ist die Nutzung einer Overlay-Struktur. Ob es da einen Weg gibt, habe ich nicht probiert, da ich die Nutzung von Methoden in Strukturen pervers finde. Eine Implementierung in Klassen scheint mir besser angebracht. Strukturen sind zwar schneller als Objekte, da sie im Stack gehalten werden. Intensive Nutzung kann aber schnell zum Überlauf des Stacks führen.
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks -
.
Dein Vorschlag funktioniert ... aber nur einmal. Jedes Mal, wenn ich tStr.Value neu zuweise, müsste ich erneut tStr.SetRef(tProp) aufrufen. Dabei wäre mir schon das erste Mal zu viel.
Das liegt daran, das Du ja die Referenz immer wieder überschreibst.
In VB.Net wird bei Strings bei der Zuweisung von Konstanten immer ein neuer Verweis gesetzt.
str1 = "Text1"
str1 = "Neuer Text"
Dabei ist es nicht so, dass str1 eine immer gleiche Referenz ist die nur den Inhalt wechselt.
Es ist tatsächlich so, das str1 zunächst auf die Konstante "Text1" verweist und dann auf "Neuer Text"
Ein Lösung Deines Problems könntest DU aber mit dem Typ Stringbuilder erreichen. Der Stringbuilder legt zunächst eine Instanz (Referenz) an, und es kann später auch nur der Inhalt verändert werden.
Nachfolgend Dein Beispiel mit Stringbuilder. Zur Verdeutlichung wird der Inhalt der Referenzvariable zweimal verändert.
Hier das Beispiel:
Public Sub TSub() Dim tProp As StringBuilder = New StringBuilder("irgendetwas") Dim tStr As TStruc = New TStruc(tProp) 'tStr.SetRef(tProp) tStr.Value = "was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp.ToString()) tStr.Value = "noch was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp.ToString()) Console.ReadLine() End Sub Public Structure TStruc Private rValue As StringBuilder Private _pValue As String Private Property _value As String Public Property Value As String Get Return _value End Get Set(ByVal nValue As String) _value = nValue _pValue = nValue rValue.Clear() rValue.Append(nValue) End Set End Property Public Sub New(ByRef pValue As StringBuilder) _value = pValue.ToString() _pValue = pValue.ToString() rValue = pValue End Sub End Structure
_pvalue wird hier nicht mehr benötigt ich habe die Variable aber nicht entfernt.
Grüße
Roland
- Bearbeitet Roland Franz Dienstag, 20. Juni 2017 17:52
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 23. Juni 2017 06:21
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 3. Juli 2017 13:19
- Tag als Antwort aufgehoben Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 3. Juli 2017 14:02
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 4. Juli 2017 06:06
-
Guten Morgen Peter und Roland und herzlichen Dank.
Zunächst Peter:
Ich hatte es geahnt, dass es maximal mit Krücke gehen wird. Ich bin aber auch kein Krückenfan.
Allerdings war mir so, als hätte ich das in C# schon einmal elegant lösen können.
Entweder bilde ich mir das nur ein oder VB ist eben doch nicht mit C# auf eine Stufe zu stellen...
Sodann Roland:
Danke. Das ist eine gute Idee.
Es ist zwar auch eine Krücke und mir ist mit Blick auf die Konsequenzen Laufzeitverhalten, Stackoverflowpotenzial und die Gesichter der Anwender auch nicht ganz wohl dabei.
Aber aus jetziger Sicht ist es eine verwendbare Krücke, die ich auch anwenden und durchsetzen werde.
Nochmals besten Dank.
Gruß
Werner
WM
-
Hallo WM,
das mit der Krücke scheint nur so.
Das ist die einzige und auch korrekte und empfohlen Methode wenn es darum geht mit Strings und Referenzen zu arbeiten.
Wenn Dir der Type Stringbuilder nicht zusagt, ist es eine Kleinigkeit eine eigene Klasse zB. myString zu verwenden.
Nachfolgend ein Beispiel mit der myString Klasse:
Public Sub TSub() Dim tProp As myString = New myString("irgendewas") Dim tStr As TStruc = New TStruc(tProp) tStr.Value = "was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp.Value) tStr.Value = "noch was ganz anderes" Console.WriteLine("Strukturwert : {0}", tStr.Value) Console.WriteLine("Eigenschaftswert : {0}", tProp.Value) Console.ReadLine() End Sub Public Structure TStruc Private rValue As myString Private Property _value As String Public Property Value As String Get Return _value End Get Set(ByVal nValue As String) _value = nValue rValue.Value = nValue End Set End Property Public Sub New(ByRef pValue As myString) _value = pValue.Value rValue = pValue End Sub End Structure Public Class myString Private _value As String Private newPropertyValue As String Public Property Value() As String Get Return _value End Get Set(ByVal value As String) _value = value End Set End Property Public Sub New(value As String) _value = value End Sub End Class
Grüße
Roland
PS:Du hast wahrscheinlich aus versehen Deinen Kommentar auf meine Anwort als Antwort markiert, könntest Du das bitte noch korrigieren, damit bei einer Suche von anderen Mitgliedernauch die Lösung auf die Frage gefunden wird ;-)
-
Danke Roland.
Das mit der Krücke war auch nicht bezüglich der Korrektheit gemeint sondern viel mehr darauf bezogen, dass meine Anwender eben einen Typ String gewohnt waren und wohl weiterhin erwarten. Da hilft auch die eigene Klasse nichts.
Aber dennoch vielen Dank für den Nachtrag.
Die Antwort sollte ich aus versehen markiert und nun wohl auch wieder zurückgenommen haben.
Viele Grüße
Werner
WM