Skip to content

Instantly share code, notes, and snippets.

@mcintyre321
Last active August 13, 2018 23:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcintyre321/957dbfe941818fa54a32c428029a9e94 to your computer and use it in GitHub Desktop.
Save mcintyre321/957dbfe941818fa54a32c428029a9e94 to your computer and use it in GitHub Desktop.
Ctor.Args
public static class CTor
{
public static object[] Args<T>(Func<Type, object> create = null)
{
create = create ?? ((type) => {
if (type.IsValueType)
{
return Activator.CreateInstance(type);
};
return null;
});
return typeof(T).GetConstructors().OrderBy(c => c.GetParameters().Count()).First()
.GetParameters().Select(c => create(c.ParameterType)).ToArray();
}
public static object[] Args<T>(Expression<Func<T>> construct)
{
return ((NewExpression)construct.Body).Arguments
.Select(a => ResolveValue(a))
.ToArray();
}
static object ResolveValue(Expression a)
{
var constantExp = a as ConstantExpression;
if (constantExp != null) return constantExp.Value;
var fieldExp = a as MemberExpression;
if (fieldExp != null) return GetMemberConstant(fieldExp);
var methodCallExp = a as MethodCallExpression;
if (methodCallExp != null)
{
var parameters = methodCallExp.Arguments.Select(arg => ResolveValue(arg)).ToArray();
return methodCallExp.Method.Invoke(ResolveValue(methodCallExp.Object), parameters);
}
var invocationExpression = a as InvocationExpression;
if (invocationExpression != null)
{
var parameters = invocationExpression.Arguments.Select(arg => ResolveValue(arg)).ToArray();
var x = (Delegate)ResolveValue(invocationExpression.Expression);
return x.DynamicInvoke(parameters);
}
var binaryExpression = a as BinaryExpression;
if (binaryExpression != null)
{
switch (binaryExpression.NodeType)
{
case ExpressionType.Multiply:
return ((dynamic)ResolveValue(binaryExpression.Left)) * ((dynamic)ResolveValue(binaryExpression.Right));
case ExpressionType.Add:
return ((dynamic)ResolveValue(binaryExpression.Left)) + ((dynamic)ResolveValue(binaryExpression.Right));
case ExpressionType.Divide:
return ((dynamic)ResolveValue(binaryExpression.Left)) / ((dynamic)ResolveValue(binaryExpression.Right));
case ExpressionType.Subtract:
return ((dynamic)ResolveValue(binaryExpression.Left)) - ((dynamic)ResolveValue(binaryExpression.Right));
default:
break;
}
}
throw new NotImplementedException();
}
private static object GetMemberConstant(MemberExpression node)
{
object value;
if (node.Member.MemberType == MemberTypes.Field)
{
var fieldInfo = (FieldInfo)node.Member;
var instance = (node.Expression == null) ? null : TryEvaluate(node.Expression).Value;
value = fieldInfo.GetValue(instance);
}
else if (node.Member.MemberType == MemberTypes.Property)
{
var propertyInfo = (PropertyInfo)node.Member;
var instance = (node.Expression == null) ? null : TryEvaluate(node.Expression).Value;
value = propertyInfo.GetValue(instance, null);
}
else
{
throw new NotSupportedException();
}
return value;
}
private static ConstantExpression TryEvaluate(Expression expression)
{
if (expression.NodeType == ExpressionType.Constant)
{
return (ConstantExpression)expression;
}
throw new NotSupportedException();
}
}
@mcintyre321
Copy link
Author

MIT Licenced or Public Domain

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment