I haven't seen any examples like this, so hopefully this isn't a duplicate. I have a process that's given this string:
Line1=LineOne;Line2=LineTwo;City=City;State=StateOrProvidence;Zip=PostalCode
I need to turn this into an AddressField object:
public class AddressField
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
I'm not finding a simple way to do this. Trying to split it into a dictionary or list, but nothing is working as easily as I hoped. Also it has to be in DotNet Framework 4.6.2 without any extra add-ins.
Any suggestions? Thanks.
CodePudding user response:
One idea would be to create a static method on the class that returns an instance of the class based on an input string. You could split the string on the semi-colon character, and then split each result on the equals sign, ending up with the key-value pairs for each property. Then you could use a switch statement to parse the pairs and set the appropriate property values:
public class AddressField
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public static AddressField FromString(string input)
{
if (input == null) return null;
AddressField result = new AddressField();
foreach(var kvp in input.Split(';'))
{
var parts = kvp.Split('=');
if (parts.Length == 2)
{
switch(parts[0])
{
case "Line1":
result.Line1 = parts[1];
break;
case "Line2":
result.Line2 = parts[1];
break;
case "City":
result.City = parts[1];
break;
case "State":
result.State = parts[1];
break;
case "Zip":
result.Zip = parts[1];
break;
}
}
}
return result;
}
}
Example usage:
var addressField = AddressField.FromString("Line1=LineOne;Line2=LineTwo;City=City;State=StateOrProvidence;Zip=PostalCode");
CodePudding user response:
The simple solution
Create a Parse()
function to manually assign values
public class AddressField
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public override string ToString()
{
return $"Line1={Line1};Line2={Line2};City={Line1};State={State};Zip={Zip}";
}
public static AddressField Parse(string line)
{
AddressField result = new AddressField();
string[] parts = line.Split(';');
foreach (var item in parts)
{
string[] values = item.Split('=');
switch (values[0])
{
case "Line1":
result.Line1 = values[1];
break;
case "Line2":
result.Line2 = values[1];
break;
case "City":
result.City = values[1];
break;
case "State":
result.State = values[1];
break;
case "Zip":
result.Zip = values[1];
break;
}
}
return result;
}
}
and test it with
static void Main(string[] args)
{
string input = "Line1=LineOne;Line2=LineTwo;City=City;State=StateOrProvidence;Zip=PostalCode";
AddressField address = AddressField.Parse(input);
Console.WriteLine(address);
}
Of course, a lot of checks are missing here to create robust code. The above is just for illustrative purposes.
The Dynamic Solution
You can use a ExpandObject
to build a type on the go as you parse values, and then convert into a AddressField
.
public class AddressField
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public override string ToString()
{
return $"Line1={Line1};Line2={Line2};City={Line1};State={State};Zip={Zip}";
}
public static AddressField Parse(string line)
{
dynamic obj = new ExpandoObject();
IDictionary<string, object> properties = obj;
string[] parts = line.Split(';');
foreach (var item in parts)
{
string[] values = item.Split('=');
properties[values[0]] = values[1];
}
return new AddressField()
{
Line1 = obj.Line1,
Line2 = obj.Line2,
City = obj.City,
State = obj.State,
Zip = obj.Zip,
};
}
}