I am currently using FieldInfo.GetValue and FieldInfo.SetValue quite a lot in my programm, which is significantly slowing up my programm.
For PropertyInfo I use the GetValueGetter and GetValueSetter methods so I only use reflection once for a given type. For the FieldInfo, the methods don't exist.
What is the suggested approach for FieldInfo?
EDIT:
I followed this useful link from CodeCaster's reply. This is a great search direction.
Now the "only" point that I don't get in this answer is how I can cache the getters / setters and re-use them in a generic way, using only the field's name - which is basically what the SetValue is doing
// generate the cache
Dictionary<string, object> setters = new Dictionary<string, object>();
Type t = this.GetType();
foreach (FieldInfo fld in t.GetFields()) {
MethodInfo method = t.GetMethod("CreateSetter");
MethodInfo genericMethod = method.MakeGenericMethod( new Type[] {this.GetType(), fld.FieldType});
setters.Add(fld.Name, genericMethod.Invoke(null, new[] {fld}));
}
// now how would I use these setters?
setters[fld.Name].Invoke(this, new object[] {newValue}); // => doesn't work without cast....
You could use Expressions to generate faster field accessors. If you want them to work on Object rather than the field's concrete type, you'd have to add casts (Convert) in the expression.
using System.Linq.Expressions;
class FieldAccessor
{
private static readonly ParameterExpression fieldParameter = Expression.Parameter(typeof(object));
private static readonly ParameterExpression ownerParameter = Expression.Parameter(typeof(object));
public FieldAccessor(Type type, string fieldName)
{
var field = type.GetField(fieldName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field == null) throw new ArgumentException();
var fieldExpression = Expression.Field(
Expression.Convert(ownerParameter, type), field);
Get = Expression.Lambda<Func<object, object>>(
Expression.Convert(fieldExpression, typeof(object)),
ownerParameter).Compile();
Set = Expression.Lambda<Action<object, object>>(
Expression.Assign(fieldExpression,
Expression.Convert(fieldParameter, field.FieldType)),
ownerParameter, fieldParameter).Compile();
}
public Func<object, object> Get { get; }
public Action<object, object> Set { get; }
}
Usage:
class M
{
private string s;
}
var accessors = new Dictionary<string, FieldAccessor>();
// expensive - you should do this only once
accessors.Add("s", new FieldAccessor(typeof(M), "s"));
var m = new M();
accessors["s"].Set(m, "Foo");
var value = accessors["s"].Get(m);
Related
I recently found how to add an event when changing a property of an Item in my ListView :
foreach (Profil item in gp.ListProfils)
{
if (item is INotifyPropertyChanged)
{
INotifyPropertyChanged observable = (INotifyPropertyChanged)item;
observable.PropertyChanged +=
new PropertyChangedEventHandler(ItemPropertyChanged);
}
}
Now, I would like to apply the modify to all selected items.
I found how to identify the name of property changed :
private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(sender is Profil)
{
string myPropertyName = e.PropertyName;
Profil editedProfile = (Profil)sender;
foreach(Profil prf in this.SelectedProfiles)
{
//prf.NAME_PROPERTY = editedProfile.NAME_PROPERTY
if (!this.ListProfilToEdit.Contains(editedProfile))
{
this.ListProfilToEdit.Add(editedProfile);
}
}
}
}
But how can I replace the line in comment.
Concretely if I edited the field "Width", I want to change the width for all selected elements.
Is there a way to do it, without creating a separated function EditProperty(string nameProperty)?
Here you need to be able to read a property dynamically from an object and then write it dynamically on another object.
You can use Expression Trees to generate Getters & Setters dynamically and them put in the cache.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace CoreAppMain
{
public class TypeAccessors<T> where T : class
{
//Getters
public static Dictionary<string, Func<T, object>> Getters = GetTypeGetters();
private static Dictionary<string, Func<T, object>> GetTypeGetters()
{
var _getters = new Dictionary<string, Func<T, object>>();
var props = typeof(T).GetProperties();
foreach (var p in props)
{
var entityParam = Expression.Parameter(typeof(T), "e");
Expression columnExpr = Expression.Property(entityParam, p);
Expression conversion = Expression.Convert(columnExpr, typeof(object));
var fct = Expression.Lambda<Func<T, object>>(conversion, entityParam).Compile();
_getters.Add(p.Name, fct);
}
return _getters;
}
//setters
public static Dictionary<string, Action<T, object>> Setters = GetTypeSetters();
public static Dictionary<string, Action<T, object>> GetTypeSetters()
{
var setters = new Dictionary<string, Action<T, object>>();
const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
var propsToSet = typeof(T).GetProperties(flags)
.Where(x => x.CanWrite)
.ToList();
foreach (var field in propsToSet)
{
var propertyInfo = typeof(T).GetProperty(field.Name);
setters.Add(field.Name, GetPropertySetter<T>(propertyInfo));
}
return setters;
}
public static Action<TModel, object> GetPropertySetter<TModel>(PropertyInfo propertyInfo)
{
// Note that we are testing whether this is a value type
bool isValueType = propertyInfo.DeclaringType.IsValueType;
var method = propertyInfo.GetSetMethod(true);
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
// Note that we are using Expression.Unbox for value types
// and Expression.Convert for reference types
Expression<Action<TModel, object>> expr =
Expression.Lambda<Action<TModel, object>>(
Expression.Call(
isValueType ?
Expression.Unbox(obj, method.DeclaringType) :
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj, value);
Action<TModel, object> action = expr.Compile();
return action;
}
}
}
Usage Example:
var cust1 = new Customer()
{
FirstName = "TOTOT",
LastName = "TITI"
};
var cust2 = new Customer()
{
FirstName = "XXXXXX",
LastName = "YYYYYY"
};
var value = TypeAccessors<Customer>.Getters[nameof(Customer.FirstName)](cust2);
TypeAccessors<Customer>.Setters[nameof(Customer.FirstName)](cust1, value);
Console.WriteLine(cust1.FirstName);
Console.ReadKey();
Is there a way to do it, without creating a separated function EditProperty(string nameProperty)?
Creating a separate method or not is a matter of good design and clean code, it does not affect the core of the question in any way. You can always create a separate method or write the code in your existing method.
But how can I replace the line in comment.
It is not exactly clear what you are doing, so I am in doubt whether what you are asking could be solved in different way, but as it is, you are asking to read and write properties of instances by only knowing their names. You will need to use Reflection for this.
For performing late binding, accessing methods on types created at run time. See the topic Dynamically Loading and Using Types.
Assuming your properties are public, this should work:
var propertyInfo = typeof(Profil).GetProperty(myPropertyName);
var value = propertyInfo.GetValue(editedProfile, null);
foreach(Profil prf in this.SelectedProfiles)
{
propertyInfo.SetValue(prf, value);
// ...other code.
}
That said, be careful using reflection, for further reading:
Reflection: Is using reflection still “bad” or “slow”?
If reflection is inefficient, when is it most appropriate?
My aim is to create a delegate at runtime which can set any field (including readonly) in any reference type to a user-specified value. Unfortunately, my current implementation throws a VerificationException at runtime when the assemblies containing the types specify the [AllowPartiallyTrustedCallers] attribute.
AssemblyOne:
[assembly: AllowPartiallyTrustedCallers]
public class TypeOne
{
public TypeOne(TypeTwo typeTwoField)
{
this.TypeTwoField = typeTwoField;
}
public TypeTwo TypeTwoField { get; }
}
AssemblyTwo:
[assembly: AllowPartiallyTrustedCallers]
public class TypeTwo
{
public TypeTwo(int i)
{
this.Int = i;
}
public int Int { get; }
}
Main:
using System;
using System.Reflection;
using System.Reflection.Emit;
using AssemblyOne;
using AssemblyTwo;
namespace Main
{
class Program
{
public class MyType
{
public MyType(TypeOne typeOneField)
{
this.TypeOneField = typeOneField;
}
public TypeOne TypeOneField { get; }
}
static void Main(string[] args)
{
var fieldInfo = typeof(TypeOne)
.GetTypeInfo()
.GetField(
"<TypeTwoField>k__BackingField",
BindingFlags.Instance | BindingFlags.NonPublic |
BindingFlags.Public);
var setter = (Action<TypeOne, TypeTwo>) GetReferenceSetter(fieldInfo);
var myType = new MyType(new TypeOne(new TypeTwo(1)));
// Throws VerificationException
setter(myType.TypeOneField, new TypeTwo(2));
}
public static Delegate GetReferenceSetter(FieldInfo field)
{
var delegateType = typeof(Action<,>)
.MakeGenericType(field.DeclaringType, field.FieldType);
var method = new DynamicMethod(
field.Name + "Set",
null,
new[] {field.DeclaringType, field.FieldType},
field.DeclaringType,
skipVisibility: true);
var emitter = method.GetILGenerator();
emitter.Emit(OpCodes.Ldarg_0);
emitter.Emit(OpCodes.Ldarg_1);
emitter.Emit(OpCodes.Stfld, field);
emitter.Emit(OpCodes.Ret);
return method.CreateDelegate(delegateType);
}
}
}
So MyType has a TypeOne which has a readonly TypeTwo. In this scenario, the DynamicMethod throws a VerificationException at runtime.
Is it possible to create such a delegate which works for any declaring type + field type which you throw at it? If so, how?
I realize that readonly fields ought never be set after construction, but the purpose of this is for deserialization & deep-copying.
Dynamic methods are quite limited in modifying their security. I suspect using an AssemblyBuilder instead may bypass the security checks, but I haven't tried that.
Instead, what may be able to achieve this is using other methods that access fields, in the TypedReference type.
public static unsafe void SetValue<T>(object inst, FieldInfo fi, T val)
{
var mi = typeof(TypedReference).GetMethod("InternalMakeTypedReference", BindingFlags.NonPublic | BindingFlags.Static);
var sig = MethodSignature.FromMethodInfo(mi);
var del = ReflectionTools.NewCustomDelegateType(sig.ReturnType, sig.ParameterTypes);
var inv = mi.CreateDelegate(del);
TypedReference tr;
var ptr = Pointer.Box(&tr, typeof(void*));
inv.DynamicInvoke(ptr, inst, new[]{fi.FieldHandle.Value}, fi.FieldType);
__refvalue(tr, T) = val;
}
FromMethodInfo and NewCustomDelegateType are from SharpUtils and are required to invoke InternalMakeTypedReference, which is able to obtain a reference to any field. Its signature looks like this:
private unsafe static extern void InternalMakeTypedReference(void* result, object target, IntPtr[] flds, RuntimeType lastFieldType);
You can replace the library methods with your own, they are needed just to build the appropriate delegate type (Action cannot be used due to the pointer). You cannot create the delegate type directly because of the internal RuntimeType. Surprisingly, DynamicInvoke works on the delegate, and the type reference is created.
However, to use this voodoo, I had to lower the security checks in the assembly a bit, so I am not sure if it also works in your assembly system:
[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1, SkipVerificationInFullTrust=true)]
Also please note that this code uses quite a number of undocumented features, and may stop working at any time. Use only at your own risk.
I have some exits code may be help you.
/// <summary>
/// create a getter delegate for a static field.
/// </summary>
/// <typeparam name="TField"></typeparam>
/// <param name="staticType">the type that contains the field. </param>
/// <param name="fieldName">the field that you want to get the value.</param>
/// <returns>the getter delegate.</returns>
public static Func<TField> CreateStaticFieldGetter<TField>(Type staticType, string fieldName)
{
var fieldInfo = staticType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static);
var body = Expression.Field(null, fieldInfo);
Expression<Func<TField>> lambda = Expression.Lambda<Func<TField>>(body);
return lambda.Compile();
}
public static Action<TField> CreateStaticFieldSetter<TField>(Type staticType, string fieldName)
{
ParameterExpression p1 = Expression.Parameter(typeof(TField), "p1");
var fieldInfo = staticType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static);
var leftExpr = Expression.Field(null, fieldInfo);
var body = Expression.Assign(leftExpr, p1);
Expression<Action<TField>> lambda = Expression.Lambda<Action<TField>>(body, p1);
return lambda.Compile();
}
public static Func<TTarget, TField> CreateInstanceFieldGetter<TTarget, TField>(string fieldName)
{
ParameterExpression p1 = Expression.Parameter(typeof(TTarget), "p1");
var fieldInfo = typeof(TTarget).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
var body = Expression.Field(Expression.Convert(p1, typeof(TTarget)), fieldInfo);
Expression<Func<TTarget, TField>> lambda = Expression.Lambda<Func<TTarget, TField>>(body, p1);
return lambda.Compile();
}
public static Action<TTarget, TProperty> CreateInstanceFieldSetter<TTarget, TProperty>(string filedName)
{
ParameterExpression p1 = Expression.Parameter(typeof(TTarget), "p1");
ParameterExpression p2 = Expression.Parameter(typeof(TProperty), "p2");
var member = typeof(TTarget).GetField(filedName, BindingFlags.NonPublic | BindingFlags.Instance);
var m1 = Expression.MakeMemberAccess(Expression.Convert(p1, typeof(TTarget)), member);
BinaryExpression body = Expression.Assign(m1, p2);
Expression<Action<TTarget, TProperty>> lambda = Expression.Lambda<Action<TTarget, TProperty>>(body, p1, p2);
return lambda.Compile();
}
I had an idea and want to know if it can work.
I have a simple classes with properties and want to generate accessors with Expressions.
But in the end I need to get a Func<Test, string> but I don't know the types when I use them.
A small example
class Program
{
static void Main(string[] args)
{
Test test = new Test();
test.TestString = "Blubb";
var actionStub = typeof(Helper).GetMethod("CreatePropertyGetter").MakeGenericMethod(new Type[] { test.GetType(), typeof(string)});
dynamic action = actionStub.Invoke(null, new object[] {test.GetType(), "TestString"});
var x = action(test);
}
}
public class Test
{
public string TestString { get; set; }
}
public static class Helper
{
public static Func<TType, TPropValueType> CreatePropertyGetter<TType, TPropValueType>(Type type,
string propertyName)
{
PropertyInfo fieldInfo = type.GetProperty(propertyName);
ParameterExpression targetExp = Expression.Parameter(typeof(TType), "target");
MemberExpression fieldExp = Expression.Property(targetExp, fieldInfo);
UnaryExpression assignExp = Expression.Convert(fieldExp, typeof(TPropValueType));
Func<TType, TPropValueType> getter =
Expression.Lambda<Func<TType, TPropValueType>>(assignExp, targetExp).Compile();
return getter;
}
}
The problem is I cant call the expression without dynamic, because I cant simple cast it to Func<object, object>
You're generating (TType target) => target.Something. Instead, generate (object target) => (object)((TType)target).Something so that you can use Func<object, object>.
It's not clear what exactly you are asking for, but here is an example how you can make it Func<object, object>:
public static class Helper
{
public static Func<object, object> CreatePropertyGetter(Type type, string propertyName)
{
var fieldInfo = type.GetProperty(propertyName);
var targetExp = Expression.Parameter(typeof(object), "target");
var fieldExp = Expression.Property(Expression.ConvertChecked(targetExp, type), fieldInfo);
var getter = Expression.Lambda<Func<object, object>>(fieldExp,targetExp).Compile();
return getter;
}
}
I'm having performance problems with using reflection.
So I decided to create delegates for the properties of my objects and so far got this:
TestClass cwp = new TestClass();
var propertyInt = typeof(TestClass).GetProperties().Single(obj => obj.Name == "AnyValue");
var access = BuildGetAccessor(propertyInt.GetGetMethod());
var result = access(cwp);
static Func<object, object> BuildGetAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
Expression<Func<object, object>> expr =
Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method),
typeof(object)),
obj);
return expr.Compile();
}
The results were highly satisfactory, about 30-40 times faster than using the conventional method (PropertyInfo.GetValue (obj, null);)
The problem is: How can I make a SetValue of a property, which works the same way? Unfortunately did not get a way.
I am doing so because I can not use methods with <T> because of the structure of my application.
This should work for you:
static Action<object, object> BuildSetAccessor(MethodInfo method)
{
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
Expression<Action<object, object>> expr =
Expression.Lambda<Action<object, object>>(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj,
value);
return expr.Compile();
}
Usage:
var accessor = BuildSetAccessor(typeof(TestClass).GetProperty("MyProperty").GetSetMethod());
var instance = new TestClass();
accessor(instance, "foo");
Console.WriteLine(instance.MyProperty);
With TestClass:
public class TestClass
{
public string MyProperty { get; set; }
}
Prints out:
foo
I think you'd be better off with CreateDelegate construct if performance is the key. Since you know the signature of the method beforehand, which here is just GetGetMethod and GetSetMethod of the PropertyInfo, you can create a delegate to execute the very method with the same signature directly. Expressions would be better suited if you need to build some logic (for which you did not have a method handle) to delegates. I did some benchmarking on different routes to this problem:
Func<S, T> Getter;
Action<S, T> Setter;
PropertyInfo Property;
public void Initialize(Expression<Func<S, T>> propertySelector)
{
var body = propertySelector.Body as MemberExpression;
if (body == null)
throw new MissingMemberException("something went wrong");
Property = body.Member as PropertyInfo;
//approaches:
//Getter = s => (T)Property.GetValue(s, null);
//Getter = memberSelector.Compile();
//ParameterExpression inst = Expression.Parameter(typeof(S));
//Getter = Expression.Lambda<Func<S, T>>(Expression.Property(inst, Property), inst).Compile();
//var inst = Expression.Parameter(typeof(S));
//Getter = Expression.Lambda<Func<S, T>>(Expression.Call(inst, Property.GetGetMethod()), inst).Compile();
//Getter = (Func<S, T>)Delegate.CreateDelegate(typeof(Func<S, T>), Property.GetGetMethod());
//Setter = (s, t) => Property.SetValue(s, t, null);
//var val = Expression.Parameter(typeof(T));
//var inst = Expression.Parameter(typeof(S));
//Setter = Expression.Lambda<Action<S, T>>(Expression.Call(inst, Property.GetSetMethod(), val),
// inst, val).Compile();
//Setter = (Action<S, T>)Delegate.CreateDelegate(typeof(Action<S, T>), Property.GetSetMethod());
}
//Actual calls (tested under loop):
public T Get(S instance)
{
//direct invocation:
//return (T)Property.GetValue(instance, null);
//calling the delegate:
//return Getter(instance);
}
public void Set(S instance, T value)
{
//direct invocation:
//Property.SetValue(instance, value, null);
//calling the delegate:
//Setter(instance, value);
}
Results for about 10000000 calls - (Get, Set):
GetValue-SetValue (direct): 3800 ms, 5500 ms
GetValue-SetValue (delegate): 3600 ms, 5300 ms
compiled expressions:
Get: Expression.Property: 280 ms
Expression.Call: 280 ms
direct compile: 280 ms
Set: 300 ms
create delegate: 130 ms, 135 ms
direct property call: 70 ms, 70 ms
I would, in your case, write:
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);
Isn't that simpler?? Had written a generic class here to handle the exact thing.
Use dynamic types. They use reflection under the hood, but they're a lot faster.
Otherwise...
There are tons of free faster reflection libraries out there with permissive licenses. I would link you, but there are too many, and I'm not sure which would suit you. Just search codeplex etc. When you find something you like, try it out.
But yeah, maybe before that, think if reflection really is the answer. Often there are other solutions.
Edit: As Requested...
http://geekswithblogs.net/SunnyCoder/archive/2009/06/26/c-4.0-dynamics-vs.-reflection.aspx
http://theburningmonk.com/2010/09/performance-test-dynamic-method-invocation-in-csharp-4/
http://www.mssoftwareconsulting.com/msswc/blog/post/C-40-and-dynamic-performance.aspx
It's common knowledge as far as I can tell.
I store a few classes in session. I want to be able to see the values of my class properties in trace viewer. By default I only the Type name MyNamespace.MyClass. I was wondering if I overwrite the .ToString() method and use reflection to loop over all the properties and construct a string like that ... it would do the trick but just wanted to see if there is anything already out there (specially since Immediate Window has this capability) which does the same ... i.e. list the class property values in trace instead of just the Name of the class.
You can try something like that:
static void Dump(object o, TextWriter output)
{
if (o == null)
{
output.WriteLine("null");
return;
}
var properties =
from prop in o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
where prop.CanRead
&& !prop.GetIndexParameters().Any() // exclude indexed properties to keep things simple
select new
{
prop.Name,
Value = prop.GetValue(o, null)
};
output.WriteLine(o.ToString());
foreach (var prop in properties)
{
output.WriteLine(
"\t{0}: {1}",
prop.Name,
(prop.Value ?? "null").ToString());
}
}
Of course, it's not very efficient because of the reflection... A better solution would be to dynamically generate and cache a dumper method for each specific type.
EDIT: here's an improved solution, that uses Linq expressions to generate a specialized dumper method for each type. Slightly more complex ;)
static class Dumper
{
private readonly static Dictionary<Type, Action<object, TextWriter>> _dumpActions
= new Dictionary<Type, Action<object, TextWriter>>();
private static Action<object, TextWriter> CreateDumper(Type type)
{
MethodInfo writeLine1Obj = typeof(TextWriter).GetMethod("WriteLine", new[] { typeof(object) });
MethodInfo writeLine1String2Obj = typeof(TextWriter).GetMethod("WriteLine", new[] { typeof(string), typeof(object), typeof(object) });
ParameterExpression objParam = Expression.Parameter(typeof(object), "o");
ParameterExpression outputParam = Expression.Parameter(typeof(TextWriter), "output");
ParameterExpression objVariable = Expression.Variable(type, "o2");
LabelTarget returnTarget = Expression.Label();
List<Expression> bodyExpressions = new List<Expression>();
bodyExpressions.Add(
// o2 = (<type>)o
Expression.Assign(objVariable, Expression.Convert(objParam, type)));
bodyExpressions.Add(
// output.WriteLine(o)
Expression.Call(outputParam, writeLine1Obj, objParam));
var properties =
from prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
where prop.CanRead
&& !prop.GetIndexParameters().Any() // exclude indexed properties to keep things simple
select prop;
foreach (var prop in properties)
{
bool isNullable =
!prop.PropertyType.IsValueType ||
prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
// (object)o2.<property> (cast to object to be passed to WriteLine)
Expression propValue =
Expression.Convert(
Expression.Property(objVariable, prop),
typeof(object));
if (isNullable)
{
// (<propertyValue> ?? "null")
propValue =
Expression.Coalesce(
propValue,
Expression.Constant("null", typeof(object)));
}
bodyExpressions.Add(
// output.WriteLine("\t{0}: {1}", "<propertyName>", <propertyValue>)
Expression.Call(
outputParam,
writeLine1String2Obj,
Expression.Constant("\t{0}: {1}", typeof(string)),
Expression.Constant(prop.Name, typeof(string)),
propValue));
}
bodyExpressions.Add(Expression.Label(returnTarget));
Expression<Action<object, TextWriter>> dumperExpr =
Expression.Lambda<Action<object, TextWriter>>(
Expression.Block(new[] { objVariable }, bodyExpressions),
objParam,
outputParam);
return dumperExpr.Compile();
}
public static void Dump(object o, TextWriter output)
{
if (o == null)
{
output.WriteLine("null");
}
Type type = o.GetType();
Action<object, TextWriter> dumpAction;
if (!_dumpActions.TryGetValue(type, out dumpAction))
{
dumpAction = CreateDumper(type);
_dumpActions[type] = dumpAction;
}
dumpAction(o, output);
}
}
Usage:
Dumper.Dump(myObject, Console.Out);
This is the code I use. I find it incredibly useful and is almost instant. The code is using the Newtonsoft JSON converter.
[System.Obsolete("ObjectDump should not be included in production code.")]
public static void Dump(this object value)
{
try
{
System.Diagnostics.Trace.WriteLine(JsonConvert.SerializeObject(value, Formatting.Indented));
}
catch (Exception exception)
{
System.Diagnostics.Trace.WriteLine("Object could not be formatted. Does it include any interfaces? Exception Message: " + exception.Message);
}
}
Add this to a common library, reference it and add it to the using clause. Can be used in the immediate window by typing YourObject.Dump() (the exact same as you'd do in linqpad).
Classes including interfaces have to be handled differently as this is simply a JSON converter. A workaround for classes that include interface implementations that I use is to remove the default empty constructor and implement a constructor using the specific instances of the interfaces.
I find JSON a very easy format to read and consider this small method invaluable for debugging.