public static string Property { get; } = "Property";
public static string Field = "Field";
static void Main(string[] args)
var program = new Program();
program.GetFieldWithField(new object[10]);
BenchmarkRunner.Run<Program>();
[ArgumentsSource(nameof(GetTime))]
public object GetFieldWithCache(object[] getObjectTimeList)
var creatorDictionary = new Dictionary<(Type type, string name), IFieldOrPropertyValueGetter>();
for (var i = 0; i < getObjectTimeList.Length; i++)
GetFieldOrPropertyValueWithCache(typeof(Foo), "Field", out var value, creatorDictionary);
getObjectTimeList[i] = value;
return getObjectTimeList;
[ArgumentsSource(nameof(GetTime))]
public object GetPropertyWithCache(object[] getObjectTimeList)
var creatorDictionary = new Dictionary<(Type type, string name), IFieldOrPropertyValueGetter>();
for (var i = 0; i < getObjectTimeList.Length; i++)
GetFieldOrPropertyValueWithCache(typeof(Foo), "Property", out var value, creatorDictionary);
getObjectTimeList[i] = value;
return getObjectTimeList;
[ArgumentsSource(nameof(GetTime))]
public object GetPropertyWithProperty(object[] getObjectTimeList)
var creatorDictionary = new Dictionary<(Type type, string name), IFieldOrPropertyValueGetter>()
{(typeof(Foo), "Property"), new DelegateValueGetter(() => Foo.Property)}
for (var i = 0; i < getObjectTimeList.Length; i++)
GetFieldOrPropertyValueWithCache(typeof(Foo), "Property", out var value, creatorDictionary);
getObjectTimeList[i] = value;
return getObjectTimeList;
[ArgumentsSource(nameof(GetTime))]
public object GetFieldWithField(object[] getObjectTimeList)
var creatorDictionary = new Dictionary<(Type type, string name), IFieldOrPropertyValueGetter>()
{(typeof(Foo), "Field"), new DelegateValueGetter(() => Foo.Field)}
for (var i = 0; i < getObjectTimeList.Length; i++)
GetFieldOrPropertyValueWithCache(typeof(Foo), "Field", out var value, creatorDictionary);
getObjectTimeList[i] = value;
return getObjectTimeList;
[ArgumentsSource(nameof(GetTime))]
public object GetFieldWithOriginMethod(object[] getObjectTimeList)
for (var i = 0; i < getObjectTimeList.Length; i++)
GetFieldOrPropertyValue(typeof(Foo), "Field", out var value);
getObjectTimeList[i] = value;
return getObjectTimeList;
[Benchmark(Baseline = true)]
[ArgumentsSource(nameof(GetTime))]
public object GetPropertyWithOriginMethod(object[] getObjectTimeList)
for (var i = 0; i < getObjectTimeList.Length; i++)
GetFieldOrPropertyValue(typeof(Foo), "Property", out var value);
getObjectTimeList[i] = value;
return getObjectTimeList;
public IEnumerable<object[]> GetTime()
foreach (var count in GetTimeInner())
yield return new object[] {new object[count]};
IEnumerable<int> GetTimeInner()
interface IFieldOrPropertyValueGetter
class DelegateValueGetter : IFieldOrPropertyValueGetter
public DelegateValueGetter(Func<object> getter)
public object GetObject()
private readonly Func<object> _getter;
class FieldValueGetter : IFieldOrPropertyValueGetter
public FieldValueGetter(FieldInfo fieldInfo)
public object GetObject()
return _fieldInfo.GetValue(null);
private readonly FieldInfo _fieldInfo;
class PropertyValueGetter : IFieldOrPropertyValueGetter
public PropertyValueGetter(PropertyInfo propertyInfo)
_propertyInfo = propertyInfo;
public object GetObject()
return _propertyInfo.GetValue(null, null);
private readonly PropertyInfo _propertyInfo;
private bool GetFieldOrPropertyValueWithCache(Type type, string name, out object value,
Dictionary<(Type type, string name), IFieldOrPropertyValueGetter> creatorDictionary)
if (!creatorDictionary.TryGetValue((type, name), out var creator))
creator = GetCreator(type, name);
creatorDictionary.Add((type, name), creator);
value = creator.GetObject();
private IFieldOrPropertyValueGetter GetCreator(Type type, string name)
field = temp.GetField(name, BindingFlags.Public | BindingFlags.Static);
return new FieldValueGetter(field);
PropertyInfo prop = null;
prop = temp.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
return new PropertyValueGetter(prop);
private bool GetFieldOrPropertyValue(Type type, string name, out object value)
field = temp.GetField(name, BindingFlags.Public | BindingFlags.Static);
value = field.GetValue(null);
PropertyInfo prop = null;
prop = temp.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
value = prop.GetValue(null, null);