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?

Était-ce utile?

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

Autres conseils

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top