Creating a class similar to System.String?

Geordielads

New member
Joined
Nov 14, 2006
Messages
3
Programming Experience
5-10
Hi

Im trying to create a class that can hold historical information about the state of the object.

i.e. I have a Surname object which on loading holds the string "Bloggs", when this is updated it keeps a record of "Bloggs" incase it needs to revert back, similar to how a datarow uses the DataRowVersion.

This isnt a huge problem until I want to access the object like a string using a default property i.e. mySurname = "Bloggs" and not mySurname.Value = "Bloggs"

Does anyone know a way of assigning a default property where I dont need to pass a parameter?

How does the String class actually work to do this?

Here is what I have so far, but this requires the assignment like mySurname.Value = "Bloggs".

Public Class SystemString

Private Current As String = ""
Private Original As String = ""

Public Property Value(Optional ByVal version As ItemVersion = ItemVersion.Current) As String
Get
If version = ItemVersion.Original Then
Return Original
Else
Return Current
End If
End Get
Set(ByVal Value As String)
Original = Current
Current = Value
End Set
End Property
End
Class

Public
Enum ItemVersion
Current = 0
Original = 1
End Enum
 
Use the 'Default' keyword, ie: Default Public Property Value ...
You have to remove Optional because a default property must have at least one required parameter.
When you do this you can use an instance like this:
VB.NET:
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] x [/SIZE][SIZE=2][COLOR=#0000ff]As [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] SystemString[/SIZE]
[SIZE=2]x(ItemVersion.Original) = [/SIZE][SIZE=2][COLOR=#800000]"hi"[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#800000]' instead of this[/COLOR][/SIZE]
[SIZE=2][COLOR=#800000]'x.Value(ItemVersion.Original) = [SIZE=2][COLOR=#800000]"hi"[/COLOR][/SIZE]
[/COLOR][/SIZE]

In the case you already knew this and I misunderstood the request, I could see this another way:
A String is a system type, when you say Dim S As String = "some" you are not accessing a property but assigning a new class instance of type string to the variable S defined as this type, "some" is aknowledged by the compiler as a String instance - they got both ends there for string type. This is the same as if I in example wrote Dim x As SystemString = New SystemString
If you were to do something similar creating your own framework and compiler you could invent @some@ as being recognized as an instance of your SystemString and say Dim x As SystemString = @some@ but you can't do this with .Net framework.
The closest you get is using the constructor Sub New with a parameter, then you can initialize it Dim x As New SystemString("some") but I guess that is well known for you.
 
John

Thanks for that. I was hoping that it would be possible to somehow get around the need for a parameter of a default property (like the optional or something similar), but from what you have said it doesnt look hopeful, and I definately dont want to get into writing my own framework. :)
 
I don't give up too easily :) While the above is all true, I've looked deeper into the conversions. You can define a CType operator for the class for conversion from string to this type. With Option Strict off you can make the implicit conversion as you asked, but you should use explicit conversion. (DirectCast can't be used because String class is not inheritable).
So you add the operator to class (I used Sub New method to set current value):
VB.NET:
[SIZE=2][COLOR=#0000ff]Public Shared [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Widening [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Operator [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]CType[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] s [/SIZE][SIZE=2][COLOR=#0000ff]As [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] SystemString[/SIZE]
[SIZE=2][COLOR=#0000ff] Return [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] SystemString(s)[/SIZE]
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Operator[/COLOR][/SIZE]
Then you can convert:
VB.NET:
'explicit
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] x [/SIZE][SIZE=2][COLOR=#0000ff]As [/COLOR][/SIZE][SIZE=2]SystemString [/SIZE][SIZE=2]= [/SIZE][SIZE=2][COLOR=#0000ff]CType[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#800000]"hi"[/COLOR][/SIZE][SIZE=2], SystemString)[/SIZE]
 
[SIZE=2]'implicit[/SIZE]
[SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] y [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] SystemString = [/SIZE][SIZE=2][COLOR=#800000]"hi"[/COLOR][/SIZE]

Edit: Since this is a widening you can use the implicit conversion also with Option Strict On :)
 
VB.NET:
[COLOR=#0000ff]Set[/COLOR][SIZE=2]([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] Value [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]Original = Current[/SIZE]
[SIZE=2]Current = Value[/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Set[/COLOR][/SIZE]

Can i just point out that this logic isnt analogous to that of a datarowed value. With datarow values the original is preserved until AcceptChanges() is called - your code you can only change the value once because the second time the alue changes, the previous change becomes the original. If you want to have the Current value modifiable 100 times, but still be able to undo to the original, re-work the logic
 
cjard,

That was just written for simplicity until I could get the main issue sorted, but thanks anyway.


JohnH,
Stupid question but where does that code actually go?
 
It would be natural to add it to the class that need it, and also if you try to put iti anywhere else you get an error saying:
Either the parameter type or the return type of this conversion operator must be of the containing type
 
Back
Top