class Program
{
static void Main(string[] args)
{
var data = new List() {
new WeatherData(){ Temperature = 15, Humidity = 65, UVindex = 6, WindDirection = "NNO", WindSpeed = 20 },
new WeatherData(){ Temperature = 16, Humidity = 65, UVindex = 6, WindDirection = "O", WindSpeed = 35 },
new WeatherData(){ Temperature = 19, Humidity = 45, UVindex = 8 , WindDirection = "W", WindSpeed = 45 },
new WeatherData(){ Temperature = 13, Humidity = 75, UVindex = 3, WindDirection = "NO", WindSpeed = 65 }
};
ProcessTemp(data);
ProcessHumidity(data);
Console.ReadLine();
}
static void ProcessTemp(List data)
{
foreach (var item in data)
Console.WriteLine($"{nameof(item.Temperature)}: {item.Temperature} °C");
}
static void ProcessHumidity(List data)
{
foreach (var item in data)
Console.WriteLine($"{nameof(item.Humidity)}: {item.Humidity} %");
}
}
It worked, check-in, time to get a beer…
As you guessed, it got rejected.
What if the customer decides to track windspeed. Just create another method to process that parameter? And another and another and …. You see where this is going.
The tip was to use a selector, like they do with the Linq extensions.
The new code looked like this:
class Program
{
static void Main(string[] args)
{
var data = new List() {
new WeatherData(){ Temperature = 15, Humidity = 65, UVindex = 6, WindDirection = "NNO", WindSpeed = 20 },
new WeatherData(){ Temperature = 16, Humidity = 65, UVindex = 6, WindDirection = "O", WindSpeed = 35 },
new WeatherData(){ Temperature = 19, Humidity = 45, UVindex = 8 , WindDirection = "W", WindSpeed = 45 },
new WeatherData(){ Temperature = 13, Humidity = 75, UVindex = 3, WindDirection = "NO", WindSpeed = 65 }
};
ProcessData(data, d => d.Temperature, d => nameof(d.Temperature), "°C");
ProcessData(data, d => d.Humidity, d => nameof(d.Humidity), "%");
ProcessData(data, d => d.UVindex, d => nameof(d.UVindex));
ProcessData(data, d => d.WindSpeed, d => nameof(d.WindSpeed), "km/h");
Console.ReadLine();
}
static void ProcessData(List data, Func<WeatherData, int> selector, Func<WeatherData, string> propertyName, string unit = null)
{
foreach (var item in data)
Console.WriteLine($"{propertyName(item)}: {selector(item)} {unit}");
}
}
Ok, the signature of the method got a bit more complex, but if you’re used to working with Linq, this is not as daunting as it looks. But imagine the processing of the data happens in some other assembly, maybe even written by someone else. You would need to edit 2 files (or tell someone to update their API), adding a method to your business logic and wherever you’d implement that method (UI, service, whatever).
With the new method, I don’t need to edit the business side and just implement the method. Only 1 place to change a single line of code, also just 1 method to test and maintain.
This example gave me a better understanding of Linq and changed my view on what is a called “a simple implementation” of something. Many lightbulbs were gotten ?