Вызов (params object []) с выражением [] - PullRequest
6 голосов
/ 25 мая 2011

Я пытаюсь вызвать String.Format из с помощью дерева Linq.Expression. Вот быстрый пример:

    var format = Expression.Constant("({0}) {1}");
    var company = Expression.Property(input, membernames.First());
    var project = Expression.Property(input, membernames.Last());
    var args = new Expression[] {format, company, project};
    var invoke = Expression.Call(method,args);

Однако проблема в том, что String.Format имеет подпись:

String.Format(string format, params object[] args)

и я пытаюсь передать выражение [].

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

String.Format("({0}) {1}", input.foo, input.bar)

Как мне вызвать функцию params через выражения Linq?

Ответы [ 2 ]

9 голосов
/ 25 мая 2011

На самом деле params просто указывает ParamArrayAttribute для этого параметра.Компилятор C # понимает это и создает массив за кулисами.

Выражения не понимают этого, поэтому вам действительно нужно создать массив самостоятельно, если вы хотите вызвать метод с params.Это также видно по тому факту, что при назначении лямбда-выражения с использованием params -метода выражению выражение содержит создание массива:

Expression<Func<string>> expression = () => string.Format("",1,2,3,4);
string expressionString = expression.ToString();

Здесь expressionString будет содержать следующую строку:

() => Format("", new [] {Convert(1), Convert(2), Convert(3), Convert(4)})

Чтобы создать выражение, создающее массив, используйте метод Expression.NewArrayInit() .

При этом, если вам нужны только два параметра (или одинили три), существует перегрузка string.Format(), которую можно использовать непосредственно из выражения.

0 голосов
/ 25 мая 2011

params - это просто синтаксический сахар.В конечном счете, параметр - это просто массив.Поэтому тип параметра должен быть object[], а выражение, описывающее такой массив, - это то, что вы должны передать в качестве второго аргумента.Другими словами, вы должны иметь только два аргумента, а не three .И второй аргумент должен быть двухэлементным массивом, содержащим то, что в настоящее время является вашим вторым и третьим аргументами.

...