Is there a more elegant way to structure the following code, which takes a comma delimited string containing certain values in specific positions and assigns the values to the properties of an object?
// split comma delimited items into a string array
Dim items As String() = myList.Split(CChar(","))
// Assign my Person object's properties
// Name
If items.Length > 0 Then
Person.FullName = items(ItemIndex.FullName)
End If
// Address1
If items.Length > 1 Then
Person.Address1 = items(ItemIndex.Address1)
End If
// Address2
If payload.Length > 2 Then
Person.Address2 = items(ItemIndex.Address2)
End If
EDIT: I'm open to C# examples, too.
-
My first instinct is to question why the input is in the form of a comma-delimited string. Assuming that you don't control the input and just have to live with it, I don't have a huge problem with this implementation. While I'm not intimately familiar with VB.net, I think there is a StringTokenizer. I would take a look at that and consider using that instead.
-
Looks fine. Are you expecting variable length arrays? You could:
If items.Length >= 3 Then // Assign properties Else Throw New NotSupportedException("The line needs to have three items"); End If -
You could use an enumerator but it's pretty much the same code just shorter.
Dim items = myList.Split(",").GetEnumerator If items.MoveNext Then FirstName = items.Current If items.MoveNext Then Address1 = items.Current If items.MoveNext Then Address2 = items.CurrentIt's pretty tough to validate coming from a comma delimited string.
Of course if you are using objects you could pass something to your object and let your object parse it. I'm assuming you are able to use Linq in the next example.
Public Class Person Private Enum Position FirstName = 0 Address1 = 1 Address2 = 2 LastName = 3 End Enum Sub FillFromArray(ByVal Values() As String) FirstName = If(Values.ElementAtOrDefault(Position.FirstName), String.Empty) Address1 = If(Values.ElementAtOrDefault(Position.Address1), String.Empty) Address2 = If(Values.ElementAtOrDefault(Position.Address2), String.Empty) LastName = If(Values.ElementAtOrDefault(Position.LastName), String.Empty) End Sub Public FirstName As String Public Address1 As String Public Address2 As String Public LastName As String End Class Module MainModule Sub Main() Dim testString As String = "FirstName,Address 1,Address 2" Dim testPerson As New Person testPerson.FillFromArray(testString.Split(",")) Debug.Assert(testPerson.FirstName = "FirstName") Debug.Assert(testPerson.Address1 = "Address 1") Debug.Assert(testPerson.Address2 = "Address 2") Debug.Assert(testPerson.LastName = String.Empty) End Sub End Module -
You could append a bunch of commas onto myList, and then you can skip the if statements:
// split comma delimited items into a string array myList = myList & ",,," // One comma for every property. Dim items As String() = myList.Split(CChar(",")) // Assign my Person object's properties Person.FullName = items(ItemIndex.FullName) Person.Address1 = items(ItemIndex.Address1) Person.Address2 = items(ItemIndex.Address2)Carl Manaster : +1 This is a bit of a hack, but I think it's the cleanest way to do it. Avoid all the conditionality by ensuring there are enough elements in the array.Eclipse : It's kind of hacky, but removing corner-cases by adding extra data is a pretty common technique. Another example is when you have a matrix and you need to apply a transformation to each cell based on its neighbours. Instead of writing extra code to handle the sides and corners, just surround the matrix with the identity value for the function and only iterate over the interior cells. -
If you wanted to rely on ItemIndex names matching the property names (convention) then you could use reflection to make it completely declarative. I can elaborate if you think that's a route you're interested in...
0 comments:
Post a Comment