patterncsharpMinor
Mapping array to class properties
Viewed 0 times
arraymappingclassproperties
Problem
I am wondering what is the best way to map array values to properties in a class. Consider the following sample array describing information for an airport:
I have the following class:
```
public class Airport
{
public Airport(string[] data)
{
Action[] PropertyMappings =
{
x=>this.Id=x,
x=>this.Ident=x,
x=>this.Type=x,
x=>this.Name=x,
x=>this.Latitude=x,
x=>this.Longtitude=x,
x=>this.Elevation=x,
x=>this.Continent=x,
x=>this.CountryIso=x,
x=>this.RegionIso=x,
x=>this.Municipality=x,
x=>this.ScheduledService=x,
x=>this.GPSCode=x,
x=>this.DataCode=x,
x=>this.LocalCode=x,
x=>this.HomeLink=x,
x=>this.WikipediaLink=x,
x=>this.Keywords=x
};
for(int i=0;i<data.Count();i++)
{
PropertyMappingsi;
}
}
public string Id { get; set; }
public string Ident { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Latitude { get; set; }
public string Longtitude { get; set; }
public string Elevation { get; set; }
public string Continent { g
[0] "6523" string
[1] "00A" string
[2] "heliport" string
[3] "Total Rf Heliport" string
[4] "40.07080078125" string
[5] "-74.9336013793945" string
[6] "11" string
[7] "NA" string
[8] "US" string
[9] "US-PA" string
[10] "Bensalem" string
[11] "no" string
[12] "00A" string
[13] "" string
[14] "00A" string
[15] "" string
[16] "" string
[17] "" stringI have the following class:
```
public class Airport
{
public Airport(string[] data)
{
Action[] PropertyMappings =
{
x=>this.Id=x,
x=>this.Ident=x,
x=>this.Type=x,
x=>this.Name=x,
x=>this.Latitude=x,
x=>this.Longtitude=x,
x=>this.Elevation=x,
x=>this.Continent=x,
x=>this.CountryIso=x,
x=>this.RegionIso=x,
x=>this.Municipality=x,
x=>this.ScheduledService=x,
x=>this.GPSCode=x,
x=>this.DataCode=x,
x=>this.LocalCode=x,
x=>this.HomeLink=x,
x=>this.WikipediaLink=x,
x=>this.Keywords=x
};
for(int i=0;i<data.Count();i++)
{
PropertyMappingsi;
}
}
public string Id { get; set; }
public string Ident { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Latitude { get; set; }
public string Longtitude { get; set; }
public string Elevation { get; set; }
public string Continent { g
Solution
As you said that you will always have the right number of elements in the array, I would suggest the following:
Depending on usage I would suggest that you alter the accessibility of the setters on the properties and consider making the default constructor protected (if you only want to create via a data array).
Why am I making this suggestion?
Edit
As RufusL notes in the comments, it would be a good idea to add a null check for the data array:
Further to my comment about my proposed solution being faster - it's not because your code is slow in any way. If you want a dictionary of mappings of property -> index in data array your code will be slower but that probably wont matter.
You could just move your array of property mappings to a field. Just change the signature to
(all of the code in the edit has just been typed directly in the browser, if it doesn't compile, hopefully it should be close enough to correct.)
public class Airport
{
public string Id { get; set; }
public string Ident { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Latitude { get; set; }
public string Longtitude { get; set; }
public string Elevation { get; set; }
public string Continent { get; set; }
public string CountryIso { get; set; }
public string RegionIso { get; set; }
public string Municipality { get; set; }
public string ScheduledService { get; set; }
public string GPSCode { get; set; }
public string DataCode { get; set; }
public string LocalCode { get; set; }
public string HomeLink { get; set; }
public string WikipediaLink { get; set; }
public string Keywords { get; set; }
public static Airport CreateFromData(string[] data)
{
if (data.Length != 18) {
throw new ArgumentException("...");
}
return new Airport
{
Id = data[0],
Ident = data[1],
Type = data[2],
Name = data[3],
Latitude = data[4],
Longtitude = data[5],
Elevation = data[6],
Continent = data[7],
CountryIso = data[8],
RegionIso = data[9],
Municipality = data[10],
ScheduledService = data[11],
GPSCode = data[12],
DataCode = data[13],
LocalCode = data[14],
HomeLink = data[15],
WikipediaLink = data[16],
Keywords = data[17]
};
}
}Depending on usage I would suggest that you alter the accessibility of the setters on the properties and consider making the default constructor protected (if you only want to create via a data array).
Why am I making this suggestion?
- Keeps it simple
- It's about 30 times faster than your method
- You can view the code as a schema for the data array. I.e.
Typeis the third element
Edit
As RufusL notes in the comments, it would be a good idea to add a null check for the data array:
public static Airport CreateFromData(string[] data)
{
if (data == null) {
throw new ArgumentNullException("data");
}
if (data.Length != 18)
{
...Further to my comment about my proposed solution being faster - it's not because your code is slow in any way. If you want a dictionary of mappings of property -> index in data array your code will be slower but that probably wont matter.
You could just move your array of property mappings to a field. Just change the signature to
Action[] you'd then populate it like:Action[] PropertyMappings =
{
(a, s) => a.Id = s,
// ...
}
public static Airport CreateFromData(string[] data)
{
// Guards omitted.
var result = new Airport();
for (var i = 0; i < data.Length; i++)
{
PropertyMappings(result, data[i]);
}
return result;
}(all of the code in the edit has just been typed directly in the browser, if it doesn't compile, hopefully it should be close enough to correct.)
Code Snippets
public class Airport
{
public string Id { get; set; }
public string Ident { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Latitude { get; set; }
public string Longtitude { get; set; }
public string Elevation { get; set; }
public string Continent { get; set; }
public string CountryIso { get; set; }
public string RegionIso { get; set; }
public string Municipality { get; set; }
public string ScheduledService { get; set; }
public string GPSCode { get; set; }
public string DataCode { get; set; }
public string LocalCode { get; set; }
public string HomeLink { get; set; }
public string WikipediaLink { get; set; }
public string Keywords { get; set; }
public static Airport CreateFromData(string[] data)
{
if (data.Length != 18) {
throw new ArgumentException("...");
}
return new Airport
{
Id = data[0],
Ident = data[1],
Type = data[2],
Name = data[3],
Latitude = data[4],
Longtitude = data[5],
Elevation = data[6],
Continent = data[7],
CountryIso = data[8],
RegionIso = data[9],
Municipality = data[10],
ScheduledService = data[11],
GPSCode = data[12],
DataCode = data[13],
LocalCode = data[14],
HomeLink = data[15],
WikipediaLink = data[16],
Keywords = data[17]
};
}
}public static Airport CreateFromData(string[] data)
{
if (data == null) {
throw new ArgumentNullException("data");
}
if (data.Length != 18)
{
...Action<Airport, string>[] PropertyMappings =
{
(a, s) => a.Id = s,
// ...
}
public static Airport CreateFromData(string[] data)
{
// Guards omitted.
var result = new Airport();
for (var i = 0; i < data.Length; i++)
{
PropertyMappings(result, data[i]);
}
return result;
}Context
StackExchange Code Review Q#76922, answer score: 8
Revisions (0)
No revisions yet.