Я экспериментирую с более эффективными способами создания форм.Мои эксперименты связаны с возможностью связывать строки и другие типы напрямую по ссылкам на их классы и использовать их для обновления исходных значений без какого-либо строго типизированного кода.
Я использовал GCHandle.AddrOfPinnedObject, чтобы получить адрес памяти строки, но он дает адрес памяти строковых данных, а не класс / ссылку на строку, которые мне нужно изменить, чтобы позволить мне использоватьэтот подход.
Я знаю, что строки являются неизменяемыми и не могут быть изменены (На самом деле, вы можете, но это не рекомендуется), но я не хочу изменять фактические строки, но изменить ссылку на него(строковый объект).
Есть ли другой способ получить адрес ссылки на строковый объект?
Пример кода:
Private oTestperson As New Person
Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Create the form
AddText("Name", oTestperson.Name)
AddText("Phone", oTestperson.Phone)
AddText("Address", oTestperson.Address)
End Sub
Public Sub AddText(ByVal Title As String, ByRef sValue As String)
Dim oGCHandle As System.Runtime.InteropServices.GCHandle
Dim oInputItem As New InputItem
' This does not do the job, as it only returns the address of the string data, not the reference to the string class
oGCHandle = System.Runtime.InteropServices.GCHandle.Alloc(CType(sValue, Object), System.Runtime.InteropServices.GCHandleType.Pinned)
oInputItem.Pointer = oGCHandle.AddrOfPinnedObject()
oGCHandle.Free()
' Store data
oInputItem.ID = GetID()
oInputItem.Type = InputTypes.Text
oInputItem.BaseValue = sValue
If Not Request.Form(oInputItem.ID) Then oInputItem.Value = Request.Form(oInputItem.ID)
If oInputItem.Value Is Nothing Then oInputItem.Value = sValue
' Save in collection
InputItems.Add(oInputItem)
End Sub
Private Sub linkbuttonSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles linkbuttonSave.Click
Save()
End Sub
Public Sub Save()
Dim oTest As New Person
Dim oGCHandle As System.Runtime.InteropServices.GCHandle
Dim NewStrPointer As IntPtr
' Check if something has been changed, in that case update the origional value
For Each oInputItem As InputItem In InputItems
If oInputItem.Value <> oInputItem.BaseValue Then
oGCHandle = GCHandle.Alloc(oInputItem.Value, GCHandleType.Pinned)
NewStrPointer = oGCHandle.AddrOfPinnedObject()
oGCHandle.Free()
' This fails as oInputItem.Pointer is the address of the string data, not the string class
Marshal.WriteInt32(oInputItem.Pointer.ToInt32, NewStrPointer.ToInt32)
End If
Next
End Sub
Private InputItems As New ArrayList
Private Class Person
Public Property Name As String
Public Property Phone As String
Public Property Address As String
End Class
Public Enum InputTypes As Integer
Text = 0
End Enum
Public Class InputItem
Public Property ID As String
Public Property BaseValue As Object
Public Property Value As Object
Public Property Type As InputTypes = 0
Public Property Pointer As IntPtr
End Class