Преобразование массива с использованием выражений

#c# #lambda #expression #func

Вопрос:

Нужна помощь в том, чтобы заставить этот фрагмент кода работать.

 var splits = rawTokens[startIndex   2].Value.Split(',');
var paramk = Expression.Parameter(typeof(String), "item");
                    var converter = Expression.Lambda(Expression.Convert(
                        paramk
                        , lToken.CorrespondingType), paramk);

                    var method = typeof(Array).GetMethod("ConvertAll").MakeGenericMethod(new Type[] { typeof(string), lToken.CorrespondingType });
                    var arrayBuilder = Expression.Call(method, Expression.Constant(splits), converter);
 

Это не удается с
Система.Исключение аргумента: Система «Выражение типа».Функция 2[System.String,System.String]' cannot be used for parameter of type 'System.Converter 2[Система.Строка,Система.Строка] системы «метода».Строка[] Преобразует все[Строка,Строка](Система.Строка[], Система.Преобразователь`2[Система.Строка,Система.Строка])»

Комментарии:

1. Попробуйте перейти typeof(Converter<string,string>) к Expression.Lambda() . Это идет впереди других параметров. Ну, тебе действительно нужно попасть GetGenericTypeDefinition() , а потом MakeGenericType() пройти typeof(string) и lToken.CorrespondingType .

2. Возможно, вы также захотите проверить наличие особого случая, lToken.CorrespondingType == typeof(string) потому что тогда вам не понадобится преобразование.

3. @BenVoigt Спасибо тебе. Я уже пробовал первый подход и получил ошибки принуждения. Мне обязательно понадобится это преобразование. Подумываю о том, чтобы отказаться от выражений для этого, но тогда это часть структуры, основанной на выражениях.

4. В случае, если сообщение об ошибке было неясным, выражение лямбда предположило, что оно должно быть выполнено Func<string, string> , посмотрев на типы параметров и возвращаемых значений, но Array.ConvertAll нуждалось в a Converter<string, string> . Вам придется остановить его от догадок, сказав ему, что вы хотите Converter<string, ?> , чтобы место ? было заполнено с помощью lToken.CorrespondingType .

5. Тип преобразователя Тип = тип(Преобразователь<,>); Тип[] typeArgs = { тип(строка), lToken. Соответствующий тип }; Тип closedConverterType = converterType.MakeGenericType(typeArgs); преобразователь var = Выражение. Лямбда( Выражение. Преобразовать(Выражение. Преобразование( paramk , lToken. соответствующий тип), тип закрытого преобразователя), параметр);