If something looks like a duck, swims like a duck and quacks like a duck, then it probably is a duck.
private class StaticObject
{
public int A { get ; set ; }
public string B { get ; set ; }
}
private class StaticObjectTester : ObjectTester
{
private readonly StaticObject _o = new StaticObject();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class StaticObject
{
public int A { get ; set ; }
public string B { get ; set ; }
}
private class StaticObjectTester : ObjectTester
{
private readonly StaticObject _o = new StaticObject();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class ReflectionObjectTester : ObjectTester
{
private static readonly PropertyInfo PropertyA = typeof (StaticObject).GetProperty( "A" );
private static readonly PropertyInfo PropertyB = typeof (StaticObject).GetProperty( "B" );
private static readonly object [] Empty = new object [0];
private readonly Object _o = new StaticObject();
public override int A
{
get { return ( int ) PropertyA.GetValue(_o, Empty); }
set { PropertyA.SetValue(_o, value , Empty); }
}
public override string B
{
get { return ( string ) PropertyB.GetValue(_o, Empty); }
set { PropertyB.SetValue(_o, value , Empty); }
}
}
* This source code was highlighted with Source Code Highlighter .
private class ReflectionObjectTester : ObjectTester
{
private static readonly PropertyInfo PropertyA = typeof (StaticObject).GetProperty( "A" );
private static readonly PropertyInfo PropertyB = typeof (StaticObject).GetProperty( "B" );
private static readonly object [] Empty = new object [0];
private readonly Object _o = new StaticObject();
public override int A
{
get { return ( int ) PropertyA.GetValue(_o, Empty); }
set { PropertyA.SetValue(_o, value , Empty); }
}
public override string B
{
get { return ( string ) PropertyB.GetValue(_o, Empty); }
set { PropertyB.SetValue(_o, value , Empty); }
}
}
* This source code was highlighted with Source Code Highlighter .
private class ReflectionObjectTester : ObjectTester
{
private static readonly PropertyInfo PropertyA = typeof (StaticObject).GetProperty( "A" );
private static readonly PropertyInfo PropertyB = typeof (StaticObject).GetProperty( "B" );
private static readonly object [] Empty = new object [0];
private readonly Object _o = new StaticObject();
public override int A
{
get { return ( int ) PropertyA.GetValue(_o, Empty); }
set { PropertyA.SetValue(_o, value , Empty); }
}
public override string B
{
get { return ( string ) PropertyB.GetValue(_o, Empty); }
set { PropertyB.SetValue(_o, value , Empty); }
}
}
* This source code was highlighted with Source Code Highlighter .
private class DictionaryObjectTester : ObjectTester
{
private const string AName = "A" ;
private const string BName = "B" ;
private readonly Dictionary< string , Object> _o = new Dictionary< string , object >();
public override int A
{
get { return ( int ) _o[AName]; }
set { _o[AName] = value ; }
}
public override string B
{
get { return ( string ) _o[BName]; }
set { _o[BName] = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class DictionaryObjectTester : ObjectTester
{
private const string AName = "A" ;
private const string BName = "B" ;
private readonly Dictionary< string , Object> _o = new Dictionary< string , object >();
public override int A
{
get { return ( int ) _o[AName]; }
set { _o[AName] = value ; }
}
public override string B
{
get { return ( string ) _o[BName]; }
set { _o[BName] = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class DictionaryDelegateTester : ObjectTester
{
private const string AName = "A" ;
private const string BName = "B" ;
private readonly Dictionary< string , Func<Object>> _getters;
private readonly Dictionary< string , Action<Object>> _setters;
private readonly StaticObject _o = new StaticObject();
public DictionaryDelegateTester()
{
_getters = new Dictionary< string , Func<Object>>
{
{AName, () => _o.A},
{BName, () => _o.B}
};
_setters = new Dictionary< string , Action< object >>
{
{AName, v => _o.A = ( int ) v},
{BName, v => _o.B = v.ToString()},
};
}
public override int A
{
get { return ( int ) _getters[AName](); }
set { _setters[AName]( value ); }
}
public override string B
{
get { return ( string ) _getters[BName](); }
set { _setters[BName]( value ); }
}
}
* This source code was highlighted with Source Code Highlighter .
private class DictionaryDelegateTester : ObjectTester
{
private const string AName = "A" ;
private const string BName = "B" ;
private readonly Dictionary< string , Func<Object>> _getters;
private readonly Dictionary< string , Action<Object>> _setters;
private readonly StaticObject _o = new StaticObject();
public DictionaryDelegateTester()
{
_getters = new Dictionary< string , Func<Object>>
{
{AName, () => _o.A},
{BName, () => _o.B}
};
_setters = new Dictionary< string , Action< object >>
{
{AName, v => _o.A = ( int ) v},
{BName, v => _o.B = v.ToString()},
};
}
public override int A
{
get { return ( int ) _getters[AName](); }
set { _setters[AName]( value ); }
}
public override string B
{
get { return ( string ) _getters[BName](); }
set { _setters[BName]( value ); }
}
}
* This source code was highlighted with Source Code Highlighter .
private class DynamicObjectTester : ObjectTester
{
private readonly dynamic _o = new StaticObject();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class DynamicObjectTester : ObjectTester
{
private readonly dynamic _o = new StaticObject();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class ExpandoDynamicObjectTester : ObjectTester
{
private readonly dynamic _o = new ExpandoObject();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class ExpandoDynamicObjectTester : ObjectTester
{
private readonly dynamic _o = new ExpandoObject();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
}
* This source code was highlighted with Source Code Highlighter .
private class PureDynamicObjectTester : ObjectTester
{
private readonly dynamic _o = new DynamicContainer();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
#region Nested type: DynamicContainer
private class DynamicContainer : DynamicObject
{
private int _a;
private string _b;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == "A" )
{
result = _a;
return true ;
}
if (binder.Name == "B" )
{
result = _b;
return true ;
}
return base .TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value )
{
if (binder.Name == "A" )
{
_a = ( int ) value ;
return true ;
}
if (binder.Name == "B" )
{
_b = ( string ) value ;
return true ;
}
return base .TrySetMember(binder, value );
}
}
#endregion
}
* This source code was highlighted with Source Code Highlighter .
private class PureDynamicObjectTester : ObjectTester
{
private readonly dynamic _o = new DynamicContainer();
public override int A
{
get { return _o.A; }
set { _o.A = value ; }
}
public override string B
{
get { return _o.B; }
set { _o.B = value ; }
}
#region Nested type: DynamicContainer
private class DynamicContainer : DynamicObject
{
private int _a;
private string _b;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == "A" )
{
result = _a;
return true ;
}
if (binder.Name == "B" )
{
result = _b;
return true ;
}
return base .TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value )
{
if (binder.Name == "A" )
{
_a = ( int ) value ;
return true ;
}
if (binder.Name == "B" )
{
_b = ( string ) value ;
return true ;
}
return base .TrySetMember(binder, value );
}
}
#endregion
}
* This source code was highlighted with Source Code Highlighter .
o => ((T)o).{name}
" and the setter is " (o, v) => ((T)o).{name} = v
".
public static Func< object , T> GetValueGetter<T>( this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter( typeof (Object), "i" );
var castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
var property = Expression.Property(castedInstance, propertyInfo);
var convert = Expression. Convert (property, typeof (T));
var expression = Expression.Lambda(convert, instance);
return (Func< object , T>)expression.Compile();
}
public static Action< object ,T> GetValueSetter<T>( this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter( typeof (Object), "i" );
var castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
var argument = Expression.Parameter( typeof (T), "a" );
var setterCall = Expression.Call(
castedInstance,
propertyInfo.GetSetMethod(),
Expression. Convert (argument, propertyInfo.PropertyType));
return (Action< object ,T>)Expression.Lambda(setterCall, instance, argument)
.Compile();
}
* This source code was highlighted with Source Code Highlighter .
public static Func< object , T> GetValueGetter<T>( this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter( typeof (Object), "i" );
var castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
var property = Expression.Property(castedInstance, propertyInfo);
var convert = Expression. Convert (property, typeof (T));
var expression = Expression.Lambda(convert, instance);
return (Func< object , T>)expression.Compile();
}
public static Action< object ,T> GetValueSetter<T>( this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter( typeof (Object), "i" );
var castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
var argument = Expression.Parameter( typeof (T), "a" );
var setterCall = Expression.Call(
castedInstance,
propertyInfo.GetSetMethod(),
Expression. Convert (argument, propertyInfo.PropertyType));
return (Action< object ,T>)Expression.Lambda(setterCall, instance, argument)
.Compile();
}
* This source code was highlighted with Source Code Highlighter .
private class ExpressionObjectTester : ObjectTester
{
private static readonly Func< object , int > AGetter =
typeof (StaticObject).GetProperty( "A" ).GetValueGetter< int >();
private static readonly Func< object , string > BGetter =
typeof (StaticObject).GetProperty( "B" ).GetValueGetter< string >();
private static readonly Action< object , int > ASetter =
typeof (StaticObject).GetProperty( "A" ).GetValueSetter< int >();
private static readonly Action< object , string > BSetter =
typeof (StaticObject).GetProperty( "B" ).GetValueSetter< string >();
private readonly StaticObject _o = new StaticObject();
public override int A
{
get { return AGetter(_o); }
set { ASetter(_o, value ); }
}
public override string B
{
get { return BGetter(_o); }
set { BSetter(_o, value ); }
}
}
* This source code was highlighted with Source Code Highlighter .
private class ExpressionObjectTester : ObjectTester
{
private static readonly Func< object , int > AGetter =
typeof (StaticObject).GetProperty( "A" ).GetValueGetter< int >();
private static readonly Func< object , string > BGetter =
typeof (StaticObject).GetProperty( "B" ).GetValueGetter< string >();
private static readonly Action< object , int > ASetter =
typeof (StaticObject).GetProperty( "A" ).GetValueSetter< int >();
private static readonly Action< object , string > BSetter =
typeof (StaticObject).GetProperty( "B" ).GetValueSetter< string >();
private readonly StaticObject _o = new StaticObject();
public override int A
{
get { return AGetter(_o); }
set { ASetter(_o, value ); }
}
public override string B
{
get { return BGetter(_o); }
set { BSetter(_o, value ); }
}
}
* This source code was highlighted with Source Code Highlighter .
Method name | Time | Time additive |
---|---|---|
Reflection | 00: 01: 33.6077139 | 1311.59% |
Dictionary of meanings | 00: 00: 10.8516518 | 63.64% |
Delegates dictionary | 00: 00: 12.3299023 | 85.93% |
Dynamic object with a static container | 00: 00: 10.7193446 | 61.65% |
Dynamic object with Expando | 00: 00: 09.7034082 | 46.33% |
Dynamic object with call pickup | 00: 00: 11.1040041 | 67.45% |
Compilation of expressions (Expressions) | 00: 00: 08.5675928 | 29.20% |
Source: https://habr.com/ru/post/103558/