Question

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?

Was it helpful?

Solution

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);

OTHER TIPS

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.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top