2013-11-26 2 views
1

При использовании выражений Linq для создания экземпляров следующий код отлично подходит для создания экземпляров типов с 0 аргументами.Linq Expression для создания экземпляра Type с дополнительными аргументами?

var newExpression = Expression.New(type); 

Однако, если тип есть необязательные аргументы, то есть, каждый аргумент является необязательным, так что тип по существу совместим с новым(), то этот код не удастся.

Так что, я думаю, мне нужно передать выражения для каждого аргумента, который является необязательным. Итак, как бы получить значение по умолчанию, связанное с каждым аргументом?

Как получить значения по умолчанию из ParameterInfo для каждого аргумента?

+0

С отражением: http://stackoverflow.com/q/14009359/87698 – Heinzi

ответ

3

Вы можете использовать DefaultValue свойство:

ParameterInfo parameter = // 
if(parameter.HasDefaultValue) 
{ 
    object defaultValue = parameter.DefaultValue; 
} 

И вы можете создать выражение для них с помощью 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); 
+0

Спасибо .. Я буду отмечать как ответ после истечения таймера :) –

+0

BTW, что 'ToArray()' не нужно. – svick

+0

небольшая коррекция, вам нужно передать тип параметра в качестве второго значения в выражение. Константа (p.DefaultValue, p.ParameterType) .. потому что если значение по умолчанию равно null, оно будет вводить константу как объект, вызывающий несоответствие на ctor –

2

Так что, если вы в данный конструктор, вы знаете, есть все значения по умолчанию , вы можете использовать отражение, чтобы получить их все достаточно просто.

public static Expression Construct(ConstructorInfo constructor) 
{ 
    return Expression.New(constructor, 
     constructor.GetParameters() 
     .Select(param => Expression.Constant(param.DefaultValue))); 
} 

Это все еще оставляет вам проблему поиска конструктора со всеми значениями по умолчанию.

Вы можете использовать следующий шаблон, чтобы найти все возможные допустимые конструкторы, хотя вам все равно нужно будет выбрать один из них:

typeof(Foo).GetConstructors() 
    .Where(constructor => constructor.GetParameters() 
     .All(param => param.HasDefaultValue)); 

(. Обратите внимание, что это также будет соответствовать параметру меньше конструктора)

 Смежные вопросы

  • Нет связанных вопросов^_^