Reputation: 23214
When using Linq Expressions to create instances, the following code works fine to create instances of types with 0 args.
var newExpression = Expression.New(type);
However, if the type have optional arguments, that is, every arg is optional so that the type is essentially compatible with new(), then the above code will fail.
So I guess I have to pass expressions for each arg that is optional. So how would I get the default value associated with each argument?
How do I get default values from the ParameterInfo for each arg?
Upvotes: 1
Views: 1421
Reputation: 203830
So if you have the given constructor that you know has all default values, you can use reflection to get them all simply enough.
public static Expression Construct(ConstructorInfo constructor)
{
return Expression.New(constructor,
constructor.GetParameters()
.Select(param => Expression.Constant(param.DefaultValue)));
}
This still leaves you with the problem of finding a constructor with all default values.
You can leverage the following pattern to find all possible valid constructors, although you'll still need to pick one of them:
typeof(Foo).GetConstructors()
.Where(constructor => constructor.GetParameters()
.All(param => param.HasDefaultValue));
(Note that this will also match a parameter-less constructor.)
Upvotes: 2
Reputation: 144136
You can use the DefaultValue
property:
ParameterInfo parameter = //
if(parameter.HasDefaultValue)
{
object defaultValue = parameter.DefaultValue;
}
And you can create an expression for these using Expression.Constant
:
public class SomeClass
{
public SomeClass(int i = 3, string str = "Default")
{
}
}
ConstructorInfo ci = typeof(SomeClass).GetConstructor(new[] { typeof(int), typeof(string) });
var paramExprs = ci.GetParameters().Select(p => Expression.Constant(p.DefaultValue)).ToArray();
var newExpr = Expression.New(ci, paramExprs);
Upvotes: 3