using System.Threading.Tasks;
void LogToConsole(string message);
Task LogToFileAsync(string message);
public static string DateTimeFormat_yyyyMMdd="yyyy-MM-dd";
public class FileLogger : ILogger
public void LogToConsole(string message)
Console.WriteLine(message);
public async Task LogToFileAsync(string message)
string filename = $"logfile_{DateTime.Now.ToString(Constants.DateTimeFormat_yyyyMMdd)}.log";
await File.AppendAllTextAsync(filename, message + Environment.NewLine);
public class Calculator<T> where T : struct, IConvertible
private readonly T _startValue;
private readonly ILogger _logger;
public Calculator(T startValue, ILogger logger)
_startValue = startValue;
public int DoCalculation(object arg1, T arg2)
if (arg1 is not IConvertible convertibleArg1)
throw new ArgumentException("arg1 must be convertible to int.");
int firstValue = convertibleArg1.ToInt32(null);
int secondValue = Convert.ToInt32(arg2);
int startValue = Convert.ToInt32(_startValue);
throw new DivideByZeroException("Start value must not be zero.");
return firstValue + secondValue/startValue;
LogToConsole(ex.Message);
public int HigherOrderCalculation(Func<int, int, int> operation, int x, int y)
public void LogToConsole(string message)
_logger.LogToConsole(message);
public Task LogToFileAsync(string message)
return _logger.LogToFileAsync(message);
public async static Task Main()
ILogger _logger = new FileLogger();
Calculator<double> _calculator = new Calculator<double>(1.5d, _logger);
_calculator.LogToConsole("Hello world");
await _calculator.LogToFileAsync("Hello world");
var result1 = _calculator.DoCalculation(1, 2.0);
var result2 = _calculator.HigherOrderCalculation((x, y) => x + y, 3, 4);