I have a method that looks something like this:
public static T GenerateProxy<T>(params object[] ctorArgs)
{
return proxyGenerator.CreateProxy(typeof(T), ctorArgs);
}
Basically, it's calling the appropriate constructor based on the type T and whatever arguments I provide to find a matching constructor. This works, but if the constructor changes, I don't get any compile-time errors if I change the number of arguments a constructor changes. I found a nice utility method that uses an Expression
to get the constructor arguments like so:
public static object[] GetCTorArgumentsFromSelector<T>(Expression<Func<T>> ctorCall) where T : class
{
if (ctorCall == null) throw new ArgumentNullException("ctorCall");
var newCall = ctorCall.Body as NewExpression;
if (newCall == null)
{
throw new ArgumentException("Not a constructor call.", "ctorCall");
}
int argumentCount = newCall.Arguments.Count;
var ctorArgs = new object[argumentCount];
for (int i = 0; i < ctorArgs.Length; i++)
{
var param = newCall.Arguments[i] as ConstantExpression;
if (param == null)
throw new ArgumentException("You may only place constant values in calls to the constructor.");
ctorArgs[i] = param.Value;
}
return ctorArgs;
}
So it can be used like so:
SomeClass arg = new SomeClass();
var ctorArgs = GetCTorArgumentsFromSelector(() => MyClass(arg));
var proxy = GenerateProxy<MyClass>(ctorArgs);
...which would be nice and strongly typed. So...since I don't know a whole lot about Expressions, I'm wondering if the limitation of only using constants can be worked around in any way. My example above wouldn't work because arg
isn't a constant, but it would be nice to use it this way.
I think I understand why the limitation exists, but I was hoping someone else might have a good idea of an alternative method here. Thanks in advance.
Edit - So, after some more searching, it seems I can replace ConstantExpression
with MemberExpression
, then compile and invoke it using the method found in the answer here...but I have no idea what the ramifications of this are.