c#: Call boxed delegate - c#

In my project I need to transform data between several classes so I created a class DataMapper that is used for strong-typed mapping of properties from two different classes. When properties in the pair need to be modified I store two delegates (converters) for this purpose.
Then the DataMapper has two methods Update(T source, S target) and Update(S source, T target) that use these mappings to provide the tranformation.
public class DataMapper<TSourceType, TTargetType> : IDataUpdater<TSourceType, TTargetType> {
private readonly IDictionary<PropertyInfo, PropertyInfo> _sourceToTargetMap = new Dictionary<PropertyInfo, PropertyInfo>();
private readonly IDictionary<PropertyInfo, object> _converters = new Dictionary<PropertyInfo, object>();
public DataMapper<TSourceType, TTargetType> Map<TSourceValue, TTargetValue>(
Expression<Func<TSourceType, TSourceValue>> sourcePropExpr,
Expression<Func<TTargetType, TTargetValue>> targetPropExpr)
{
_sourceToTargetMap.Add(sourcePropExpr.AsPropertyInfo(), targetPropExpr.AsPropertyInfo());
return this;
}
public DataMapper<TSourceType, TTargetType> Map<TSourceValue, TTargetValue>(
Expression<Func<TSourceType, TSourceValue>> sourcePropExpr,
Expression<Func<TTargetType, TTargetValue>> targetPropExpr,
Func<TSourceValue, TTargetValue> sourceToTargetConverter,
Func<TTargetValue, TSourceValue> targetToSourceConverter)
{
_sourceToTargetMap.Add(sourcePropExpr.AsPropertyInfo(), targetPropExpr.AsPropertyInfo());
_converters.Add(sourcePropExpr.AsPropertyInfo(), sourceToTargetConverter);
_converters.Add(targetPropExpr.AsPropertyInfo(), targetToSourceConverter);
return this;
}
public void Update(TSourceType source, TTargetType target) {
foreach (var keyValuePair in _sourceToTargetMap) {
var sourceProp = keyValuePair.Key;
var targetProp = keyValuePair.Value;
Update(source, target, sourceProp, targetProp);
}
}
public void Update(TTargetType source, TSourceType target) {
foreach (var keyValuePair in _sourceToTargetMap) {
var sourceProp = keyValuePair.Value;
var targetProp = keyValuePair.Key;
Update(source, target, sourceProp, targetProp);
}
}
private void Update(
object source,
object target,
PropertyInfo sourceProperty,
PropertyInfo targetProperty)
{
var sourceValue = sourceProperty.GetValue(source);
if (_converters.ContainsKey(sourceProperty)) {
sourceValue = typeof(InvokeHelper<,>)
.MakeGenericType(sourceProperty.PropertyType, targetProperty.PropertyType)
.InvokeMember("Call", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, new[] { _converters[sourceProperty], sourceValue });
}
targetProperty.SetValue(target, sourceValue);
}
}
Here is the usage:
public SomeClass {
private static readonly IDataUpdater<SomeClass, SomeOtherClass> _dataMapper = new DataMapper<SomeClass, SomeOtherClass>()
.Map(x => x.PropertyA, y => y.PropertyAA)
.Map(x => x.PropertyB, y => y.PropertyBB, x => Helper.Encrypt(x), y => Helper.Decrypt(y));
public string PropertyA { get; set; }
public string PropertyB { get; set; }
public void LoadFrom(SomeOtherClass source) {
_dataMapper.Update(source, this);
}
public void SaveTo(SomeOtherClass target) {
_dataMapper.Update(this, target);
}
}
You can see in class DataHelper in the last overload of method Update that when I want to call the stored converter function, I use helper class InvokeHelper, because I didn't found other way how to call boxed delegate Func. Code for class InvokeHelper is simple - just single static method:
public static class InvokeHelper<TSource, TTarget> {
public static TTarget Call(Func<TSource, TTarget> converter, TSource source) {
return converter(source);
}
}
Is there a way how to do it without reflection? I need to optimalize these transformations for speed.
Thanks.

You can use Delegate.DynamicInvoke to invoke the delegate. Or, use dynamic:
((dynamic)(Delegate)_converters[sourceProperty])(sourceValue);
The (Delegate) cast is not necessary. It's for documentation and runtime assertion purposes. Leave it out if you don't like it.
Actually, you better use delegate instead of object in the dictionary.

If it were me, I would use a little meta-coding with expressions to create a list of compiled and strongly typed delegates. When you call the Update method, you can go through each Action in the list and update the destination from the source.
No reflection and all of the compiling and such is done once, ahead of the Update call.
public class DataMapper<TSourceType, TTargetType> : IDataUpdater<TSourceType, TTargetType>
{
List<Action<TSourceType, TTargetType>> _mappers = new List<Action<TSourceType, TTargetType>>();
DataMapper<TTargetType, TSourceType> _reverseMapper;
public DataMapper() : this(false) { }
public DataMapper(bool isReverse)
{
if (!isReverse)
{
_reverseMapper = new DataMapper<TTargetType, TSourceType>(isReverse: true);
}
}
public DataMapper<TSourceType, TTargetType> Map<TSourceValue, TTargetValue>(
Expression<Func<TSourceType, TSourceValue>> sourcePropExpr,
Expression<Func<TTargetType, TTargetValue>> targetPropExpr)
{
var mapExpression = Expression.Assign(targetPropExpr.Body, sourcePropExpr.Body);
_mappers.Add(
Expression.Lambda<Action<TSourceType, TTargetType>>(
mapExpression,
sourcePropExpr.Parameters[0],
targetPropExpr.Parameters[0])
.Compile());
if (_reverseMapper != null) _reverseMapper.Map(targetPropExpr, sourcePropExpr);
return this;
}
public DataMapper<TSourceType, TTargetType> Map<TSourceValue, TTargetValue>(
Expression<Func<TSourceType, TSourceValue>> sourcePropExpr,
Expression<Func<TTargetType, TTargetValue>> targetPropExpr,
Func<TSourceValue, TTargetValue> sourceToTargetConverter,
Func<TTargetValue, TSourceValue> targetToSourceConverter)
{
var convertedSourceExpression = Expression.Invoke(Expression.Constant(sourceToTargetConverter), sourcePropExpr.Body);
var mapExpression = Expression.Assign(targetPropExpr.Body, convertedSourceExpression);
_mappers.Add(
Expression.Lambda<Action<TSourceType, TTargetType>>(
mapExpression,
sourcePropExpr.Parameters[0],
targetPropExpr.Parameters[0])
.Compile());
if (_reverseMapper != null) _reverseMapper.Map(targetPropExpr, sourcePropExpr, targetToSourceConverter, sourceToTargetConverter);
return this;
}
public void Update(TSourceType source, TTargetType target)
{
foreach (var mapper in _mappers)
{
mapper(source, target);
}
}
public void Update(TTargetType source, TSourceType target)
{
if (_reverseMapper != null)
{
_reverseMapper.Update(source, target);
}
else
{
throw new Exception("Reverse mapper is null. Did you reverse twice?");
};
}
}
The expression is built by taking the expressions that are passed in and using them as parts for the new expression.
Say you called .Map(x => x.PropertyA, y => y.PropertyAA). You now have 2 expressions each with a parameter x and y and each with a body x.PropertyA and y.PropertyAA.
Now you want to re-assemble these expression parts into an assignment expression like y.PropertyAA = x.PropertyA. This is done in the line var mapExpression = Expression.Assign(targetPropExpr.Body, sourcePropExpr.Body); which gives you an expected expression.
Now when you call Expression.Lambda, you are incorporating the parameters (x,y) into a new expression that looks like (x,y) = > y.PropertyAA = x.PropertyA.
Before you can execute this, you need to compile it, hence the .Compile(). But since you only need to compile this once for any given map, you can compile and store the result. The uncompiled expression is of type Expression<Action<TSourceType,TTargetType>> and after it is compiled the resulting type is Action<TSourceType,TTargetType>

Related

How can I call a reflected Func<T, T> property using Expression Trees

I have a generic class with a lambda property defined as such:
public class Transformation<TProperty> : TransformationBase
{
public Func<TProperty, TProperty> Transform { get; private set; }
...
I'm trying to compile an Action that can call this Transform property (on a property of Foo). I don't know TProperty at compile-time. I've started with this:
private static Action<Foo> Compile(Transformation transformation)
{
var fooParameter = Expression.Parameter(typeof(Foo));
var changePropertyValue = Expression.Constant(transformation);
var transformProperty = Expression.Property(changePropertyValue, "Transform");
var transfromCall = Expression.Call(transformProperty, ?
}
How can I call/execute the transformProperty?
EDIT: Foo (which is known a compile time) has an untyped property Value which needs to be transformed using the Transform property of the Transformation:
public class Foo {
public object Value { get; set; }
}
So, hand-written as an example where TProperty is string it would be:
Foo foo = ... // coming from an external source
Transformation<string> tranformation = ... // coming from an external source
foo.Value = transformation.Transform((string)foo.Value);
Except that I don't know the exact type of the Transformation as it is defined in an external assembly. So, instead of string it could be int or something else. That's why I want to use Expression Trees to compile an Action for a given transformation, such that I can call:
Foo foo = ... // coming from an external source
TransformationBase transformation = ... // coming from an external source
Action<Foo> transform = Compile(transformation);
transform(foo); // should transform foo.Value using the Transform property of 'transformation'
Note: I made Transformation inherit from TransformationBase to clarify this discussion.
Your problems relate more to the lack of typing around your problem. Foo.Value is loosely typed, but your transform functions are strongly typed. Expression Trees are also strongly typed. Using them doesn't allow you to magically call code in a loosely typed manner.
The solution is either a lot of reflection, or some easy dynamic:
EDIT: I added CompileUntyped which uses ExpressionTrees.I also added CompileReflection, which uses Reflection without ExpressionTrees. I would recommend the one that uses dynamic. It is by far the easiest to read, hence the easiest to maintain.
class Program
{
static void Main(string[] args)
{
var testTransform = new Transformation<string>
{
Transform = s => s.ToUpper()
};
var a = Compile(testTransform);
var foo = new Foo
{
Value = "test"
};
a(foo);
//foo.Value is now TEST
}
public static Action<Foo> CompileReflection(TransformationBase transformation)
{
var f = transformation
.GetType()
.GetProperty("Transform")
.GetGetMethod()
.Invoke(transformation, null) as Delegate;
return foo => foo.Value = f.DynamicInvoke(foo.Value);
}
public static Action<Foo> Compile(TransformationBase transformation)
{
return new Action<Foo>(f =>
{
dynamic d = f.Value;
dynamic t = transformation;
f.Value = t.Transform(d);
});
}
public static Action<Foo> CompileUntyped(TransformationBase transformation)
{
var transformType = transformation.GetType();
var genericType = transformType.GetGenericArguments().First();
var fooParam = Expression.Parameter(typeof(Foo), "f");
var valueGetter = typeof(Foo).GetProperty("Value").GetGetMethod();
var valueSetter = typeof(Foo).GetProperty("Value").GetSetMethod();
var transformFuncMember = transformType.GetProperty("Transform").GetGetMethod();
//Equivalent to f => f.Value = transformation.Transform((T)f.Value)
//Where T is the generic type parameter of the Transformation, and f is of type Foo
var expression = Expression.Lambda<Action<Foo>>(
Expression.Call(
fooParam,
valueSetter,
Expression.Invoke(
Expression.Property(
Expression.Constant(transformation, transformType),
transformFuncMember
),
Expression.Convert(
Expression.Property(fooParam, valueGetter),
genericType
)
)
), fooParam
);
return expression.Compile();
}
}
public class TransformationBase { }
public class Transformation<TProperty> : TransformationBase
{
public Func<TProperty, TProperty> Transform { get; set; }
}
public class Foo
{
public object Value { get; set; }
}
Not sure what are you trying to do BUT if I understand your intentions - I do not see need for compiling Expressions:
private static Action<TProperty> Compile<TProperty>(Transformation<TProperty> transformation)
{
return new Action<TProperty>(p => transformation.Transform(p));
}
See an example, it should give you what you want.
void Main()
{
var dummyObject = new Dummy { Test = "Hello!" };
var propertyTransform = Create(dummyObject, "Test");
propertyTransform(dummyObject);
Console.WriteLine("Final transformation " + dummyObject.Test);
}
class Dummy {
public string Test { get; set; }
}
// Define other methods and classes here
public class Transformation<TProperty>
{
public Func<TProperty, TProperty> Transform { get; set; }
}
public static Action<TObj> Create<TObj>(TObj myObject, string property){
var prop = myObject
.GetType()
.GetProperty(property);
var val = prop.GetValue(myObject);
var transformation = Create((dynamic)val);
var transform = transformation.Transform;
return obj => {
var newValue = transform((dynamic)val);
prop.SetValue(myObject, newValue);
};
}
public static Transformation<TProperty> Create<TProperty>(TProperty property){
var transformation = new Transformation<TProperty>();
// just a dummy hijacking.
if(typeof(TProperty)==typeof(string)){
Func<string, string> test = input => "I am changed man!";
transformation.Transform = (dynamic)test;
}
return transformation;
}
Output:
Final transformation I am changed man!

Instantiating Immutable Objects With Reflection

I created a base class to help me reduce boilerplate code of the initialization of the immutable Objects in C#,
I'm using lazy initialization in order to try not to impact performance a lot ,
I was wondering how much am I affecting the performance by doing this?
This is my base class:
public class ImmutableObject<T>
{
private readonly Func<IEnumerable<KeyValuePair<string, object>>> initContainer;
protected ImmutableObject() {}
protected ImmutableObject(IEnumerable<KeyValuePair<string,object>> properties)
{
var fields = GetType().GetFields().Where(f=> f.IsPublic);
var fieldsAndValues =
from fieldInfo in fields
join keyValuePair in properties on fieldInfo.Name.ToLower() equals keyValuePair.Key.ToLower()
select new {fieldInfo, keyValuePair.Value};
fieldsAndValues.ToList().ForEach(fv=> fv.fieldInfo.SetValue(this,fv.Value));
}
protected ImmutableObject(Func<IEnumerable<KeyValuePair<string,object>>> init)
{
initContainer = init;
}
protected T setProperty(string propertyName, object propertyValue, bool lazy = true)
{
Func<IEnumerable<KeyValuePair<string, object>>> mergeFunc = delegate
{
var propertyDict = initContainer == null ? ObjectToDictonary () : initContainer();
return propertyDict.Select(p => p.Key == propertyName? new KeyValuePair<string, object>(propertyName, propertyValue) : p).ToList();
};
var containerConstructor = typeof(T).GetConstructors()
.First( ce => ce.GetParameters().Count() == 1 && ce.GetParameters()[0].ParameterType.Name == "Func`1");
return (T) (lazy ? containerConstructor.Invoke(new[] {mergeFunc}) : DictonaryToObject<T>(mergeFunc()));
}
private IEnumerable<KeyValuePair<string,object>> ObjectToDictonary()
{
var fields = GetType().GetFields().Where(f=> f.IsPublic);
return fields.Select(f=> new KeyValuePair<string,object>(f.Name, f.GetValue(this))).ToList();
}
private static object DictonaryToObject<T>(IEnumerable<KeyValuePair<string,object>> objectProperties)
{
var mainConstructor = typeof (T).GetConstructors()
.First(c => c.GetParameters().Count()== 1 && c.GetParameters().Any(p => p.ParameterType.Name == "IEnumerable`1") );
return mainConstructor.Invoke(new[]{objectProperties});
}
public T ToObject()
{
var properties = initContainer == null ? ObjectToDictonary() : initContainer();
return (T) DictonaryToObject<T>(properties);
}
}
Can be implemented like so:
public class State:ImmutableObject<State>
{
public State(){}
public State(IEnumerable<KeyValuePair<string,object>> properties):base(properties) {}
public State(Func<IEnumerable<KeyValuePair<string, object>>> func):base(func) {}
public readonly int SomeInt;
public State someInt(int someInt)
{
return setProperty("SomeInt", someInt);
}
public readonly string SomeString;
public State someString(string someString)
{
return setProperty("SomeString", someString);
}
}
and can be used like this:
//creating new empty object
var state = new State();
// Set fields, will return an empty object with the "chained methods".
var s2 = state.someInt(3).someString("a string");
// Resolves all the "chained methods" and initialize the object setting all the fields by reflection.
var s3 = s2.ToObject();
As was already mentioned in the comments, it would make more sense, not to "conflate" the immutable instance implementation or interface with the behavior of what is essentially a builder for new instances.
You could make a much cleaner and quite type safe solution that way. So we could define some marker interfaces and type safe versions thereof:
public interface IImmutable : ICloneable { }
public interface IImmutableBuilder { }
public interface IImmutableOf<T> : IImmutable where T : class, IImmutable
{
IImmutableBuilderFor<T> Mutate();
}
public interface IImmutableBuilderFor<T> : IImmutableBuilder where T : class, IImmutable
{
T Source { get; }
IImmutableBuilderFor<T> Set<TFieldType>(string fieldName, TFieldType value);
IImmutableBuilderFor<T> Set<TFieldType>(string fieldName, Func<T, TFieldType> valueProvider);
IImmutableBuilderFor<T> Set<TFieldType>(Expression<Func<T, TFieldType>> fieldExpression, TFieldType value);
IImmutableBuilderFor<T> Set<TFieldType>(Expression<Func<T, TFieldType>> fieldExpression, Func<TFieldType, TFieldType> valueProvider);
T Build();
}
And provide all the required basic builder behavior in a class like below. Note that most error checking/compiled delegate creation is omitted for the sake of brevity/simplicity. A cleaner, performance optimized version with a reasonable level of error checking can be found in this gist.
public class DefaultBuilderFor<T> : IImmutableBuilderFor<T> where T : class, IImmutableOf<T>
{
private static readonly IDictionary<string, Tuple<Type, Action<T, object>>> _setters;
private List<Action<T>> _mutations = new List<Action<T>>();
static DefaultBuilderFor()
{
_setters = GetFieldSetters();
}
public DefaultBuilderFor(T instance)
{
Source = instance;
}
public T Source { get; private set; }
public IImmutableBuilderFor<T> Set<TFieldType>(string fieldName, TFieldType value)
{
// Notes: error checking omitted & add what to do if `TFieldType` is not "correct".
_mutations.Add(inst => _setters[fieldName].Item2(inst, value));
return this;
}
public IImmutableBuilderFor<T> Set<TFieldType>(string fieldName, Func<T, TFieldType> valueProvider)
{
// Notes: error checking omitted & add what to do if `TFieldType` is not "correct".
_mutations.Add(inst => _setters[fieldName].Item2(inst, valueProvider(inst)));
return this;
}
public IImmutableBuilderFor<T> Set<TFieldType>(Expression<Func<T, TFieldType>> fieldExpression, TFieldType value)
{
// Error checking omitted.
var memberExpression = fieldExpression.Body as MemberExpression;
return Set<TFieldType>(memberExpression.Member.Name, value);
}
public IImmutableBuilderFor<T> Set<TFieldType>(Expression<Func<T, TFieldType>> fieldExpression, Func<TFieldType, TFieldType> valueProvider)
{
// Error checking omitted.
var memberExpression = fieldExpression.Body as MemberExpression;
var getter = fieldExpression.Compile();
return Set<TFieldType>(memberExpression.Member.Name, inst => valueProvider(getter(inst)));
}
public T Build()
{
var result = (T)Source.Clone();
_mutations.ForEach(x => x(result));
return result;
}
private static IDictionary<string, Tuple<Type, Action<T, object>>> GetFieldSetters()
{
// Note: can be optimized using delegate setter creation (IL).
return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(x => !x.IsLiteral)
.ToDictionary(
x => x.Name,
x => SetterEntry(x.FieldType, (inst, val) => x.SetValue(inst, val)));
}
private static Tuple<Type, Action<T, object>> SetterEntry(Type type, Action<T, object> setter)
{
return Tuple.Create(type, setter);
}
}
Example usage
This could then be used like this, using your example class of State:
public static class Example
{
public class State : IImmutableOf<State>
{
public State(int someInt, string someString)
{
SomeInt = someInt;
SomeString = someString;
}
public readonly int SomeInt;
public readonly string SomeString;
public IImmutableBuilderFor<State> Mutate()
{
return new DefaultBuilderFor<State>(this);
}
public object Clone()
{
return base.MemberwiseClone();
}
public override string ToString()
{
return string.Format("{0}, {1}", SomeInt, SomeString);
}
}
public static void Run()
{
var original = new State(10, "initial");
var mutatedInstance = original.Mutate()
.Set("SomeInt", 45)
.Set(x => x.SomeString, "Hello SO")
.Build();
Console.WriteLine(mutatedInstance);
mutatedInstance = original.Mutate()
.Set(x => x.SomeInt, val => val + 10)
.Build();
Console.WriteLine(mutatedInstance);
}
}
With the following output:
45, Hello SO
20, initial
Well to answer your question about performance, reflection is very expensive (relatively speaking). I would not use your design if it's in performance critical code.
When it comes to generics and reflection the performance hit can often be surprisingly large. Consider even something as simple as this:
public class Builder<T> where T : new()
{
public T Build()
{
return new T();
}
}
What this is actually doing is calling Activator.CreateInstance which uses reflection and it's extremely expensive.
If I wanted to optimize code like the above case I would use dynamic methods. And the performance difference between the two would be drastic.
Of course, keep in mind we're entering the zone of advanced code that's more complex and harder to read for the sake of performance. You could consider this overly optimized and overkill in code that isn't performance critical.
But in code that I write I avoid reflection like the plague.
My favourite way to things like that is to use expression trees. You can manually construct your expression tree to just create a new instance of your type and compile this expression tree into a delegate. The beauty of this approach is that you only need reflection and dynamic code generation for once and afterwards you work with the generated delegate. Also, the expression compiler does its best to work even on partial trusted environments, where dynamic methods are problematic. On the other hand, you have an abstraction layer much higher than writing pure IL code in an ILGenerator, which would be the way to go in a dynamic method.

C# Reflection: Fastest Way to Update a Property Value?

Is this the fastest way to update a property using reflection? Assume the property is always an int:
PropertyInfo counterPropertyInfo = GetProperty();
int value = (int)counterPropertyInfo.GetValue(this, null);
counterPropertyInfo.SetValue(this, value + 1, null);
I did some benchmarking here when you know the type arguments (a non generic approach wont be very different). CreateDelegate would be the fastest approach for a property if you can't directly access it. With CreateDelegate you get a direct handle to GetGetMethod and GetSetMethod of the PropertyInfo, hence reflection is not used every time.
public static Func<S, T> BuildGetAccessor<S, T>(Expression<Func<S, T>> propertySelector)
{
return propertySelector.GetPropertyInfo().GetGetMethod().CreateDelegate<Func<S, T>>();
}
public static Action<S, T> BuildSetAccessor<S, T>(Expression<Func<S, T>> propertySelector)
{
return propertySelector.GetPropertyInfo().GetSetMethod().CreateDelegate<Action<S, T>>();
}
// a generic extension for CreateDelegate
public static T CreateDelegate<T>(this MethodInfo method) where T : class
{
return Delegate.CreateDelegate(typeof(T), method) as T;
}
public static PropertyInfo GetPropertyInfo<S, T>(this Expression<Func<S, T>> propertySelector)
{
var body = propertySelector.Body as MemberExpression;
if (body == null)
throw new MissingMemberException("something went wrong");
return body.Member as PropertyInfo;
}
So now you call:
TestClass cwp = new TestClass();
var access = BuildGetAccessor((TestClass t) => t.AnyValue);
var result = access(cwp);
Or even better you can encapsulate the logic in a dedicated class to have a get and set methods on it.
Something like:
public class Accessor<S>
{
public static Accessor<S, T> Create<T>(Expression<Func<S, T>> memberSelector)
{
return new GetterSetter<T>(memberSelector);
}
public Accessor<S, T> Get<T>(Expression<Func<S, T>> memberSelector)
{
return Create(memberSelector);
}
public Accessor()
{
}
class GetterSetter<T> : Accessor<S, T>
{
public GetterSetter(Expression<Func<S, T>> memberSelector) : base(memberSelector)
{
}
}
}
public class Accessor<S, T> : Accessor<S>
{
Func<S, T> Getter;
Action<S, T> Setter;
public bool IsReadable { get; private set; }
public bool IsWritable { get; private set; }
public T this[S instance]
{
get
{
if (!IsReadable)
throw new ArgumentException("Property get method not found.");
return Getter(instance);
}
set
{
if (!IsWritable)
throw new ArgumentException("Property set method not found.");
Setter(instance, value);
}
}
protected Accessor(Expression<Func<S, T>> memberSelector) //access not given to outside world
{
var prop = memberSelector.GetPropertyInfo();
IsReadable = prop.CanRead;
IsWritable = prop.CanWrite;
AssignDelegate(IsReadable, ref Getter, prop.GetGetMethod());
AssignDelegate(IsWritable, ref Setter, prop.GetSetMethod());
}
void AssignDelegate<K>(bool assignable, ref K assignee, MethodInfo assignor) where K : class
{
if (assignable)
assignee = assignor.CreateDelegate<K>();
}
}
Short and simple. You can carry around an instance of this class for every "class-property" pair you wish to get/set.
Usage:
Person p = new Person { Age = 23 };
var ageAccessor = Accessor<Person>(x => x.Age);
int age = ageAccessor[p]; //gets 23
ageAccessor[p] = 45; //sets 45
Bit bad use of indexers here, you may replace it with dedicated "Get" and "Set" methods, but very intuitive to me :)
To avoid having to specify type each time like,
var ageAccessor = Accessor<Person>(x => x.Age);
var nameAccessor = Accessor<Person>(x => x.Name);
var placeAccessor = Accessor<Person>(x => x.Place);
I made the base Accessor<> class instantiable, which means you can do
var personAccessor = new Accessor<Person>();
var ageAccessor = personAccessor.Get(x => x.Age);
var nameAccessor = personAccessor.Get(x => x.Name);
var placeAccessor = personAccessor.Get(x => x.Place);
Having a base Accessor<> class means you can treat them as one type, for eg,
var personAccessor = new Accessor<Person>();
var personAccessorArray = new Accessor<Person>[]
{
personAccessor.Get(x => x.Age),
personAccessor.Get(x => x.Name),
personAccessor.Get(x => x.Place);
};
You should look at FastMember (nuget, source code], it's really fast comparing to reflection.
I've tested these 3 implementations:
PropertyInfo.SetValue
PropertyInfo.SetMethod
FastMember
The benchmark needs a benchmark function:
static long Benchmark(Action action, int iterationCount, bool print = true)
{
GC.Collect();
var sw = new Stopwatch();
action(); // Execute once before
sw.Start();
for (var i = 0; i <= iterationCount; i++)
{
action();
}
sw.Stop();
if (print) System.Console.WriteLine("Elapsed: {0}ms", sw.ElapsedMilliseconds);
return sw.ElapsedMilliseconds;
}
A fake class:
public class ClassA
{
public string PropertyA { get; set; }
}
Some test methods:
private static void Set(string propertyName, string value)
{
var obj = new ClassA();
obj.PropertyA = value;
}
private static void FastMember(string propertyName, string value)
{
var obj = new ClassA();
var type = obj.GetType();
var accessors = TypeAccessor.Create(type);
accessors[obj, "PropertyA"] = "PropertyValue";
}
private static void SetValue(string propertyName, string value)
{
var obj = new ClassA();
var propertyInfo = obj.GetType().GetProperty(propertyName);
propertyInfo.SetValue(obj, value);
}
private static void SetMethodInvoke(string propertyName, string value)
{
var obj = new ClassA();
var propertyInfo = obj.GetType().GetProperty(propertyName);
propertyInfo.SetMethod.Invoke(obj, new object[] { value });
}
The script itself:
var iterationCount = 100000;
var propertyName = "PropertyA";
var value = "PropertyValue";
Benchmark(() => Set(propertyName, value), iterationCount);
Benchmark(() => FastMember(propertyName, value), iterationCount);
Benchmark(() => SetValue(propertyName, value), iterationCount);
Benchmark(() => SetMethodInvoke(propertyName, value), iterationCount);
Results for 100 000 iterations:
Default setter : 3ms
FastMember: 36ms
PropertyInfo.SetValue: 109ms
PropertyInfo.SetMethod: 91ms
Now you can choose yours !!!
Just be sure that you are caching the PropertyInfo somehow, so that you aren't repeatably calling type.GetProperty. Other than that it would probably be faster if you created a delegate to a method on the type that performed the increment, or like Teoman suggested make the type implement an interface and use that.

How do you give a C# Auto-Property a default value using a custom attribute?

How do you give a C# Auto-Property a default value, using a custom attribute?
This is the code I want to see:
class Person
{
[MyDefault("William")]
public string Name { get; set; }
}
I am aware that there is no built in method to initialize the default using an attribute - can I write my own custom class that uses my custom attributes to initialize the default?
If you want to do it with PostSharp (as your tags suggest) then use a Lazy Loading aspect. You can see the one I built here http://programmersunlimited.wordpress.com/2011/03/23/postsharp-weaving-community-vs-professional-reasons-to-get-a-professional-license/
With an aspect you can apply default value to a single property or apply it to multiple properties with a single declaration at the class level.
Lazy loading aspect will use LocationInterceptionAspect base class.
[Serializable]
[LazyLoadingAspect(AttributeExclude=true)]
[MulticastAttributeUsage(MulticastTargets.Property)]
public class LazyLoadingAspectAttribute : LocationInterceptionAspect
{
public object DefaultValue {get; set;}
public override void OnGetValue(LocationInterceptionArgs args)
{
args.ProceedGetValue();
if (args.Value != null)
{
return;
}
args.Value = DefaultValue;
args.ProceedSetValue();
}
}
then apply the aspect like so
[LazyLoadingAspect(DefaultValue="SomeValue")]
public string MyProp { get; set; }
You could use a helper class like that:
public class DefaultValueHelper
{
public static void InitializeDefaultValues<T>(T obj)
{
var properties =
(from prop in obj.GetType().GetProperties()
let attr = GetDefaultValueAttribute(prop)
where attr != null
select new
{
Property = prop,
DefaultValue = attr.Value
}).ToArray();
foreach (var p in properties)
{
p.Property.SetValue(obj, p.DefaultValue, null);
}
}
private static DefaultValueAttribute GetDefaultValueAttribute(PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(DefaultValueAttribute), true)
.Cast<DefaultValueAttribute>()
.FirstOrDefault();
}
}
And call InitializeDefaultValues in the constructor of your class.
class Foo
{
public Foo()
{
DefaultValueHelper.InitializeDefaultValues(this);
}
[DefaultValue("(no name)")]
public string Name { get; set; }
}
EDIT: updated version, which generates and caches a delegate to do the initialization. This is to avoid using reflection every time the method is called for a given type.
public static class DefaultValueHelper
{
private static readonly Dictionary<Type, Action<object>> _initializerCache;
static DefaultValueHelper()
{
_initializerCache = new Dictionary<Type, Action<object>>();
}
public static void InitializeDefaultValues(object obj)
{
if (obj == null)
return;
var type = obj.GetType();
Action<object> initializer;
if (!_initializerCache.TryGetValue(type, out initializer))
{
initializer = MakeInitializer(type);
_initializerCache[type] = initializer;
}
initializer(obj);
}
private static Action<object> MakeInitializer(Type type)
{
var arg = Expression.Parameter(typeof(object), "arg");
var variable = Expression.Variable(type, "x");
var cast = Expression.Assign(variable, Expression.Convert(arg, type));
var assignments =
from prop in type.GetProperties()
let attr = GetDefaultValueAttribute(prop)
where attr != null
select Expression.Assign(Expression.Property(variable, prop), Expression.Constant(attr.Value));
var body = Expression.Block(
new ParameterExpression[] { variable },
new Expression[] { cast }.Concat(assignments));
var expr = Expression.Lambda<Action<object>>(body, arg);
return expr.Compile();
}
private static DefaultValueAttribute GetDefaultValueAttribute(PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(DefaultValueAttribute), true)
.Cast<DefaultValueAttribute>()
.FirstOrDefault();
}
}
If to speculate with Expressions you could make initializing delegates and cache them. It will make code much faster comparing with just pure reflection.
internal static class Initializer
{
private class InitCacheEntry
{
private Action<object, object>[] _setters;
private object[] _values;
public InitCacheEntry(IEnumerable<Action<object, object>> setters, IEnumerable<object> values)
{
_setters = setters.ToArray();
_values = values.ToArray();
if (_setters.Length != _values.Length)
throw new ArgumentException();
}
public void Init(object obj)
{
for (int i = 0; i < _setters.Length; i++)
{
_setters[i](obj, _values[i]);
}
}
}
private static Dictionary<Type, InitCacheEntry> _cache = new Dictionary<Type, InitCacheEntry>();
private static InitCacheEntry MakeCacheEntry(Type targetType)
{
var setters = new List<Action<object, object>>();
var values = new List<object>();
foreach (var propertyInfo in targetType.GetProperties())
{
var attr = (DefaultAttribute) propertyInfo.GetCustomAttributes(typeof (DefaultAttribute), true).FirstOrDefault();
if (attr == null) continue;
var setter = propertyInfo.GetSetMethod();
if (setter == null) continue;
// we have to create expression like (target, value) => ((TObj)target).setter((T)value)
// where T is the type of property and obj is instance being initialized
var targetParam = Expression.Parameter(typeof (object), "target");
var valueParam = Expression.Parameter(typeof (object), "value");
var expr = Expression.Lambda<Action<object, object>>(
Expression.Call(Expression.Convert(targetParam, targetType),
setter,
Expression.Convert(valueParam, propertyInfo.PropertyType)),
targetParam, valueParam);
var set = expr.Compile();
setters.Add(set);
values.Add(attr.DefaultValue);
}
return new InitCacheEntry(setters, values);
}
public static void Init(object obj)
{
Type targetType = obj.GetType();
InitCacheEntry init;
if (!_cache.TryGetValue(targetType, out init))
{
init = MakeCacheEntry(targetType);
_cache[targetType] = init;
}
init.Init(obj);
}
}
You could create a method like this:
public static void FillProperties<T>(T obj)
{
foreach (var property in typeof(T).GetProperties())
{
var attribute = property
.GetCustomAttributes(typeof(DefaultValueAttribute), true)
.Cast<DefaultValueAttribute>()
.SingleOrDefault();
if (attribute != null)
property.SetValue(obj, attribute.Value, null);
}
}
You can then either use a factory method that calls this method or call it directly from the constructor. Note that this usage of reflection is probably not a good idea if you create a lot of objects this way and performance is important.

Linq expressions and extension methods to get property name

I was looking at this post that describes a simple way to do databinding between POCO properties: Data Binding POCO Properties
One of the comments by Bevan included a simple Binder class that can be used to accomplish such data binding. It works great for what I need but I would like to implement some of the suggestions that Bevan made to improve the class, namely:
Checking that source and target are
assigned
Checking that the properties
identified by sourcePropertyName and
targetPropertyName exist
Checking for type compatibility
between the two properties
Also, given that specifying properties by string is error prone, you could use Linq expressions and extension methods instead. Then instead of writing
Binder.Bind( source, "Name", target, "Name")
you could write
source.Bind( Name => target.Name);
I'm pretty sure I can handle the first three (though feel free to include those changes) but I have no clue how to use Linq expressions and extension methods to be able to write code without using property name strings.
Any tips?
Here is the original code as found in the link:
public static class Binder
{
public static void Bind(
INotifyPropertyChanged source,
string sourcePropertyName,
INotifyPropertyChanged target,
string targetPropertyName)
{
var sourceProperty
= source.GetType().GetProperty(sourcePropertyName);
var targetProperty
= target.GetType().GetProperty(targetPropertyName);
source.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
targetProperty.SetValue(target, sourceValue, null);
}
};
target.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
sourceProperty.SetValue(source, targetValue, null);
}
};
}
}
The following will return a property name as a string from a lambda expression:
public string PropertyName<TProperty>(Expression<Func<TProperty>> property)
{
var lambda = (LambdaExpression)property;
MemberExpression memberExpression;
if (lambda.Body is UnaryExpression)
{
var unaryExpression = (UnaryExpression)lambda.Body;
memberExpression = (MemberExpression)unaryExpression.Operand;
}
else
{
memberExpression = (MemberExpression)lambda.Body;
}
return memberExpression.Member.Name;
}
Usage:
public class MyClass
{
public int World { get; set; }
}
...
var c = new MyClass();
Console.WriteLine("Hello {0}", PropertyName(() => c.World));
UPDATE
public static class Extensions
{
public static void Bind<TSourceProperty, TDestinationProperty>(this INotifyPropertyChanged source, Expression<Func<TSourceProperty, TDestinationProperty>> bindExpression)
{
var expressionDetails = GetExpressionDetails<TSourceProperty, TDestinationProperty>(bindExpression);
var sourcePropertyName = expressionDetails.Item1;
var destinationObject = expressionDetails.Item2;
var destinationPropertyName = expressionDetails.Item3;
// Do binding here
Console.WriteLine("{0} {1}", sourcePropertyName, destinationPropertyName);
}
private static Tuple<string, INotifyPropertyChanged, string> GetExpressionDetails<TSourceProperty, TDestinationProperty>(Expression<Func<TSourceProperty, TDestinationProperty>> bindExpression)
{
var lambda = (LambdaExpression)bindExpression;
ParameterExpression sourceExpression = lambda.Parameters.FirstOrDefault();
MemberExpression destinationExpression = (MemberExpression)lambda.Body;
var memberExpression = destinationExpression.Expression as MemberExpression;
var constantExpression = memberExpression.Expression as ConstantExpression;
var fieldInfo = memberExpression.Member as FieldInfo;
var destinationObject = fieldInfo.GetValue(constantExpression.Value) as INotifyPropertyChanged;
return new Tuple<string, INotifyPropertyChanged, string>(sourceExpression.Name, destinationObject, destinationExpression.Member.Name);
}
}
Usage:
public class TestSource : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; set; }
}
public class TestDestination : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Id { get; set; }
}
class Program
{
static void Main(string[] args)
{
var x = new TestSource();
var y = new TestDestination();
x.Bind<string, string>(Name => y.Id);
}
}
This question is very similar to: Retrieving Property name from lambda expression
(Cross-posting answer from https://stackoverflow.com/a/17220748/1037948)
I don't know if you need to bind to "subproperties", but inspecting the lambda.Body for Member.Name will only return the "final" property, not a "fully-qualified" property.
ex) o => o.Thing1.Thing2 would result in Thing2, not Thing1.Thing2.
This is problematic when trying to use this method to simplify EntityFramework DbSet.Include(string) with expression overloads.
So you can "cheat" and parse the Expression.ToString instead. Performance seemed comparable in my tests, so please correct me if this is a bad idea.
The Extension Method
/// <summary>
/// Given an expression, extract the listed property name; similar to reflection but with familiar LINQ+lambdas. Technique #via https://stackoverflow.com/a/16647343/1037948
/// </summary>
/// <remarks>Cheats and uses the tostring output -- Should consult performance differences</remarks>
/// <typeparam name="TModel">the model type to extract property names</typeparam>
/// <typeparam name="TValue">the value type of the expected property</typeparam>
/// <param name="propertySelector">expression that just selects a model property to be turned into a string</param>
/// <param name="delimiter">Expression toString delimiter to split from lambda param</param>
/// <param name="endTrim">Sometimes the Expression toString contains a method call, something like "Convert(x)", so we need to strip the closing part from the end</pa ram >
/// <returns>indicated property name</returns>
public static string GetPropertyName<TModel, TValue>(this Expression<Func<TModel, TValue>> propertySelector, char delimiter = '.', char endTrim = ')') {
var asString = propertySelector.ToString(); // gives you: "o => o.Whatever"
var firstDelim = asString.IndexOf(delimiter); // make sure there is a beginning property indicator; the "." in "o.Whatever" -- this may not be necessary?
return firstDelim < 0
? asString
: asString.Substring(firstDelim+1).TrimEnd(endTrim);
}//-- fn GetPropertyNameExtended
(Checking for the delimiter might even be overkill)
This is likely more than or not exactly what you asked for but I've done something similar to handle mapping of a property between two objects:
public interface IModelViewPropagationItem<M, V>
where M : BaseModel
where V : IView
{
void SyncToView(M model, V view);
void SyncToModel(M model, V view);
}
public class ModelViewPropagationItem<M, V, T> : IModelViewPropagationItem<M, V>
where M : BaseModel
where V : IView
{
private delegate void VoidDelegate();
public Func<M, T> ModelValueGetter { get; private set; }
public Action<M, T> ModelValueSetter { get; private set; }
public Func<V, T> ViewValueGetter { get; private set; }
public Action<V, T> ViewValueSetter { get; private set; }
public ModelViewPropagationItem(Func<M, T> modelValueGetter, Action<V, T> viewValueSetter)
: this(modelValueGetter, null, null, viewValueSetter)
{ }
public ModelViewPropagationItem(Action<M, T> modelValueSetter, Func<V, T> viewValueGetter)
: this(null, modelValueSetter, viewValueGetter, null)
{ }
public ModelViewPropagationItem(Func<M, T> modelValueGetter, Action<M, T> modelValueSetter, Func<V, T> viewValueGetter, Action<V, T> viewValueSetter)
{
this.ModelValueGetter = modelValueGetter;
this.ModelValueSetter = modelValueSetter;
this.ViewValueGetter = viewValueGetter;
this.ViewValueSetter = viewValueSetter;
}
public void SyncToView(M model, V view)
{
if (this.ViewValueSetter == null || this.ModelValueGetter == null)
throw new InvalidOperationException("Syncing to View is not supported for this instance.");
this.ViewValueSetter(view, this.ModelValueGetter(model));
}
public void SyncToModel(M model, V view)
{
if (this.ModelValueSetter == null || this.ViewValueGetter == null)
throw new InvalidOperationException("Syncing to Model is not supported for this instance.");
this.ModelValueSetter(model, this.ViewValueGetter(view));
}
}
This allows you to create an instance of this object and then use "SyncToModel" and "SyncToView" to move values back and forth. The following piece that goes with this allows you to group multiple of these things and move data back and forth with one call:
public class ModelViewPropagationGroup<M, V> : List<IModelViewPropagationItem<M, V>>
where M : BaseModel
where V : IView
{
public ModelViewPropagationGroup(params IModelViewPropagationItem<M, V>[] items)
{
this.AddRange(items);
}
public void SyncAllToView(M model, V view)
{
this.ForEach(o => o.SyncToView(model, view));
}
public void SyncAllToModel(M model, V view)
{
this.ForEach(o => o.SyncToModel(model, view));
}
}
Usage would look something like this:
private static readonly ModelViewPropagationItem<LoginModel, ILoginView, string> UsernamePI = new ModelViewPropagationItem<LoginModel, ILoginView, string>(m => m.Username.Value, (m, x) => m.Username.Value = x, v => v.Username, (v, x) => v.Username = x);
private static readonly ModelViewPropagationItem<LoginModel, ILoginView, string> PasswordPI = new ModelViewPropagationItem<LoginModel, ILoginView, string>(m => m.Password.Value, (m, x) => m.Password.Value = x, v => v.Password, (v, x) => v.Password = x);
private static readonly ModelViewPropagationGroup<LoginModel, ILoginView> GeneralPG = new ModelViewPropagationGroup<LoginModel, ILoginView>(UsernamePI, PasswordPI);
public UserPrincipal Login_Click()
{
GeneralPG.SyncAllToModel(this.Model, this.View);
return this.Model.DoLogin();
}
Hope this helps!
var pr = typeof(CCategory).GetProperties().Select(i => i.Name).ToList(); ;
declaration:
class Foo<T> {
public string Bar<T, TResult>(Expression<Func<T, TResult>> expersion)
{
var lambda = (LambdaExpression)expersion;
MemberExpression memberExpression;
if (lambda.Body is UnaryExpression)
{
var unaryExpression = (UnaryExpression)lambda.Body;
memberExpression = (MemberExpression)unaryExpression.Operand;
}
else
{
memberExpression = (MemberExpression)lambda.Body;
}
return memberExpression.Member.Name;
}
}
Usage:
var foo = new Foo<DummyType>();
var propName = foo.Bar(d=>d.DummyProperty)
Console.WriteLine(propName); //write "DummyProperty" string in shell

Categories