質問

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?

役に立ちましたか?

解決

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

他のヒント

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top