我正在尝试更有效的方法来生成表单。我的实验可以直接通过类引用链接字符串和其他类型,并使用它来更新原始值而无需任何强类型代码。
我一直在使用GCHandle.AddrOfPinnedObject来获取字符串的内存地址,但是它给出了字符串数据的内存地址,而不是我需要更改的字符串类/引用以允许我使用这种方法。
我知道字符串是不可变的并且无法更改(Actualy,你可以,但不推荐),但我不想更改实际的字符串,而是更改对它的引用(字符串对象)。
是否有其他方法可以获取字符串对象引用的地址?
一些示例代码:
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
答案 0 :(得分:0)
批准的方法是使用反射,它会更容易,CLR将能够确保您不会在整个地方捣毁物体。
答案 1 :(得分:0)
你的方法有点像C ++ / VB6 / 90年代晚期,但努力的是10! :)
在System.Reflection上阅读iterating classes,DataBinding了解绑定(数据)类到GUI,Serialization用于读/写类。使用WPF将进一步简化任务到接近虚无(注意WPF可以通过ElementHost在WinForms中使用。