using System.Collections.Generic;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
public static void Main()
var baseMetric = new BaseJob();
Console.WriteLine(baseMetric.jobId);
Console.WriteLine("----");
var anotherJobMetric = new AnotherRegionSummary();
Console.WriteLine(anotherJobMetric.jobId);
Console.WriteLine(anotherJobMetric.projectRunConfigurationId);
Console.WriteLine(anotherJobMetric.zipSummariesCount);
var example = new ServiceExample(new MetricService(anotherJobMetric));
for (int i = 0; i <= 5000000; i++)
example.DoWorkExample1(i, 2);
Console.WriteLine("----Service ran");
Console.WriteLine(anotherJobMetric.jobId);
Console.WriteLine(anotherJobMetric.projectRunConfigurationId);
Console.WriteLine(anotherJobMetric.zipSummariesCount);
public interface BaseJobMetrics
int jobId11 { get; set; }
int jobId12 { get; set; }
int jobId13 { get; set; }
int jobId14 { get; set; }
int jobId15 { get; set; }
int jobId16 { get; set; }
int jobId17 { get; set; }
int jobId18 { get; set; }
int jobId19 { get; set; }
int jobId20 { get; set; }
public interface RegionSummaryJobMetrics : BaseJobMetrics
int projectRunConfigurationId { get; set; }
bool hasZipSummaries { get; set; }
public interface AnotherJobMetric : BaseJobMetrics
int projectRunConfigurationId { get; set; }
int zipSummariesCount { get; set; }
public class ServiceExample
public ServiceExample(MetricService service)
public void DoWorkExample1(int projectRunConfigurationId, int? zipSummariesCount = null)
_service.setPropertyOptimized("projectRunConfigurationId", projectRunConfigurationId);
_service.setPropertyOptimized("zipSummariesCount", zipSummariesCount ?? 0);
_service.setPropertyOptimized("hasZipSummaries", zipSummariesCount.HasValue);
_service.setPropertyOptimized("jobId", projectRunConfigurationId + (zipSummariesCount ?? 0));
public class MetricService
private Dictionary<string, Action<object, object>> _setDelegateDictionary;
public MetricService(AnotherRegionSummary baseJobMetrics)
_metric = baseJobMetrics;
ReflectionDelegateCache reflectionDelegateCache = new ReflectionDelegateCache();
_setDelegateDictionary = reflectionDelegateCache.GenerateDelegateDictionary<AnotherRegionSummary>();
public void setProperty(string propertyName, object value)
if (_metric.GetType().GetProperty(propertyName) != null)
_metric.GetType().GetProperty(propertyName).SetValue(_metric, value);
public void setPropertyOptimized(string propertyName, object propertyValue)
if (_setDelegateDictionary.TryGetValue(propertyName, out var setDelegate))
setDelegate(_metric, propertyValue);
public class BaseJob : BaseJobMetrics
public int jobId { get; set; }
public int jobId1 { get; set; }
public int jobId2 { get; set; }
public int jobId3 { get; set; }
public int jobId4 { get; set; }
public int jobId5 { get; set; }
public int jobId6 { get; set; }
public int jobId7 { get; set; }
public int jobId8 { get; set; }
public int jobId9 { get; set; }
public int jobId0 { get; set; }
public int jobId11 { get; set; }
public int jobId12 { get; set; }
public int jobId13 { get; set; }
public int jobId14 { get; set; }
public int jobId15 { get; set; }
public int jobId16 { get; set; }
public int jobId17 { get; set; }
public int jobId18 { get; set; }
public int jobId19 { get; set; }
public int jobId20 { get; set; }
public class RegionSummary : RegionSummaryJobMetrics
public int jobId { get; set; }
public int projectRunConfigurationId { get; set; }
public int jobId1 { get; set; }
public int jobId2 { get; set; }
public int jobId3 { get; set; }
public int jobId4 { get; set; }
public int jobId5 { get; set; }
public int jobId6 { get; set; }
public int jobId7 { get; set; }
public int jobId8 { get; set; }
public int jobId9 { get; set; }
public int jobId0 { get; set; }
public int jobId11 { get; set; }
public int jobId12 { get; set; }
public int jobId13 { get; set; }
public int jobId14 { get; set; }
public int jobId15 { get; set; }
public int jobId16 { get; set; }
public int jobId17 { get; set; }
public int jobId18 { get; set; }
public int jobId19 { get; set; }
public int jobId20 { get; set; }
public bool hasZipSummaries { get; set; }
public class AnotherRegionSummary : AnotherJobMetric
public int jobId { get; set; }
public int projectRunConfigurationId { get; set; }
public int jobId1 { get; set; }
public int jobId2 { get; set; }
public int jobId3 { get; set; }
public int jobId4 { get; set; }
public int jobId5 { get; set; }
public int jobId6 { get; set; }
public int jobId7 { get; set; }
public int jobId8 { get; set; }
public int jobId9 { get; set; }
public int jobId0 { get; set; }
public int jobId11 { get; set; }
public int jobId12 { get; set; }
public int jobId13 { get; set; }
public int jobId14 { get; set; }
public int jobId15 { get; set; }
public int jobId16 { get; set; }
public int jobId17 { get; set; }
public int jobId18 { get; set; }
public int jobId19 { get; set; }
public int jobId20 { get; set; }
public int zipSummariesCount { get; set; }
public class ReflectionDelegateCache
public Dictionary<string, Action<object, object>> GenerateDelegateDictionary<T>()
where T : class, BaseJobMetrics
var setDelegateDictionary = new Dictionary<string, Action<object, object>>();
foreach (var propertyInfo in typeof(T).GetProperties())
var accessor = BuildSetAccessor(typeof(T).GetProperty(propertyInfo.Name)?.GetSetMethod());
setDelegateDictionary.Add(propertyInfo.Name, accessor);
return setDelegateDictionary;
private Action<object, object> BuildSetAccessor(System.Reflection.MethodInfo method)
var obj = System.Linq.Expressions.Expression.Parameter(typeof(object), "o");
var value = System.Linq.Expressions.Expression.Parameter(typeof(object));
return System.Linq.Expressions.Expression.Lambda<Action<object, object>>(System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression.Convert(obj, method.DeclaringType), method, System.Linq.Expressions.Expression.Convert(value, method.GetParameters()[0].ParameterType)), obj, value).Compile();