There are at least two ways of doing this:
1.Reflection and PropertyInfo
var obj = new TestClass();
var allProps = typeof(TestClass).GetProperties();
foreach (var prop in allProps)
{
// Get propertie value
object propValue = prop.GetGetMethod().Invoke(obj, null);
//Set propertie value
prop.GetSetMethod().Invoke(obj, new object[] { propValue });
}
You should be careful with regard to performance though, just a rough test for a class with two properties setting and getting all the properties 10k times takes 0.06 seconds with reflection and 0.001 seconds if I write it by hand. So the performance hit is pretty drastic
2.Dynamic Methods
This method is more complicated but the performance is well worth it. Dynamic methods are methods which the program emits MSIL for at runtime. They get executed by the runtime as if they were created by the compiler (so the speed is very good). Using this method setting and getting 2 properties on a class 10k times took 0.004 seconds (compared to 0.06 seconds with reflection and 0.001 second by hand). Bellow is the code to generate an array of delegates for getters and setters for a certain type. Generating the dynamic can be costly so you should cache the delegates if you intend to use the multiple times (which you probably will).
//Container for getters and setters of a property
public class MyProp
{
public string PropName { get; set; }
public Func<object,object> Getter{get;set;}
public Action<object,object> Setter{get;set;}
}
public static MyProp[] CreatePropertyDelagates (Type type)
{
var allProps = type.GetProperties();
var props = new MyProp[allProps.Length];
for(int i =0;i<allProps.Length;i++)
{
var prop = allProps[i];
// Getter dynamic method the signature would be :
// object Get(object thisReference)
// { return ((TestClass)thisReference).Prop; }
DynamicMethod dmGet = new DynamicMethod("Get", typeof(object), new Type[] { typeof(object), });
ILGenerator ilGet = dmGet.GetILGenerator();
// Load first argument to the stack
ilGet.Emit(OpCodes.Ldarg_0);
// Cast the object on the stack to the apropriate type
ilGet.Emit(OpCodes.Castclass, type);
// Call the getter method passing the object on the stack as the this reference
ilGet.Emit(OpCodes.Callvirt, prop.GetGetMethod());
// If the property type is a value type (int/DateTime/..) box the value so we can return it
if (prop.PropertyType.IsValueType)
{
ilGet.Emit(OpCodes.Box, prop.PropertyType);
}
// Return from the method
ilGet.Emit(OpCodes.Ret);
// Setter dynamic method the signature would be :
// object Set(object thisReference, object propValue)
// { return ((TestClass)thisReference).Prop = (PropType)propValue; }
DynamicMethod dmSet = new DynamicMethod("Set", typeof(void), new Type[] { typeof(object), typeof(object) });
ILGenerator ilSet = dmSet.GetILGenerator();
// Load first argument to the stack and cast it
ilSet.Emit(OpCodes.Ldarg_0);
ilSet.Emit(OpCodes.Castclass, type);
// Load secons argument to the stack and cast it or unbox it
ilSet.Emit(OpCodes.Ldarg_1);
if (prop.PropertyType.IsValueType)
{
ilSet.Emit(OpCodes.Unbox_Any,prop.PropertyType);
}
else
{
ilSet.Emit(OpCodes.Castclass, prop.PropertyType);
}
// Call Setter method and return
ilSet.Emit(OpCodes.Callvirt, prop.GetSetMethod());
ilSet.Emit(OpCodes.Ret);
// Create the delegates for invoking the dynamic methods and add the to an array for later use
props[i] = new MyProp()
{
PropName = prop.Name,
Setter = (Action<object, object>)dmSet.CreateDelegate(typeof(Action<object, object>)),
Getter = (Func<object, object>)dmGet.CreateDelegate(typeof(Func<object, object>)),
};
}
return props;
}
Invocation of the dynamic methods:
// Should be cahced for further use
var testClassProps = CreatePropertyDelagates(typeof(TestClass));
var obj = new TestClass();
foreach (var p in testClassProps)
{
var propValue = p.Getter(obj);
p.Setter(obj,propValue);
}
Obs: The code above does not deal with properties that have no getter or no setter or are marked as private. This could be easily done by looking at the properties of the ProperyInfo Class and only creating the delegates if apropriate