2013-01-30 3 views
9
Cannot convert type 'System.Func<int,bool>' to 'System.Func<object,bool>' 

Попытка бросить f2 на f1:Преобразование Func <> Типы

Func<object, bool> f1 = x => true; 
    Func<int, bool> f2 = x => true; 
    f1 = (Func<object, bool>)f2; 

Пробовал функция карты решить, но на этот раз я получить

Argument 1: cannot convert from 'C' to 'A' 

исключение. по функции трансформатора (a)

Func<int, bool> f3 = Map(f2, x => x); 

    Func<C, B> Map<A, B, C>(Func<A, B> input, Func<A, C> transform) 
    { 
     return x => input(transform(x)); 
     // return x => input(transform((A)x)); not working 
    } 

Есть ли решение?

+0

не могли бы вы объяснить, почему вам нужен тип функции? вы хотите использовать одну функцию вместо другой? –

+0

Мне нужна функция в компоненте общего уровня, но эта функция связана с реализацией. и я не хочу, чтобы общие компоненты знали эту информацию о реализации. поэтому я должен использовать этот вид литья –

+0

Здесь вы совершаете ошибки типа. Это просто не так, что функция от int до bool является функцией от чего угодно до bool. Переосмыслите свой дизайн. – Ingo

ответ

9

Это должно работать:

f1 = p => f2((int)p); 

Естественно, однако, используя этот f1 произведет InvalidCastException, если вы передадите это то, что не может быть приведен к int.

Можно создать общую функцию полезности, чтобы сделать это, при условии, что тип входного f2 наследует от типа входного f1 (это верно в вашем примере - int происходит от object):

static Func<TOut, TR> ConvertFunc<TIn, TOut, TR>(Func<TIn, TR> func) where TIn : TOut 
{ 
    return p => func((TIn)p); 
} 

Затем вы можете использовать его как это:

f1 = ConvertFunc<int, object, bool>(f2); 

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


Кстати, можно получить метод Map() для компиляции, если вы поставите аргументы типа в правильном порядке:

static Func<TNewIn, TOut> Map<TOrigIn, TNewIn, TOut>(Func<TOrigIn, TOut> input, 
                 Func<TNewIn, TOrigIn> convert) 
{ 
    return x => input(convert(x)); 
} 

Вы можете назвать это так:

f1 = Map(f2, (object x) => (int)x); 

Вам нужно явно указать тип NewIn, потому что компилятор не может сделать это.

+0

это не будет вводить функцию, она скорее изменит реализацию f1-f2. Если у меня есть 'Func f1 = x => false;' Тогда ваш метод всегда будет возвращать true, поскольку он больше не f1, а f2. Я не думаю, что это правильный ответ. –

+0

@ DJ Разве это не то, что задает вопрос? Он пытается изменить реализацию 'f1' на' f2', выполнив бросок на 'f2'. – JLRishe

+0

Я никогда не вижу никаких утверждений, говорящих об этом. –

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