2013-11-23 2 views
3

Я пытался сделать что-то вродеДисперсия Func <> Аргументы

Func<string, bool> f 
Func<object, bool> F = f; 

и компилятор вызывает следующую ошибку:

Cannot implicitly convert type 'System.Func<string,bool>' to 'System.Func<object,bool>'

Однако, очевидно, можно сделать object x = "123"

ответ

5

Представьте, что вы сделали это:

Func<string, bool> fStr = str => str.Length > 10; 
Func<object, bool> fObj = fStr; 

Ну, в соответствии с подписью fObj, вы должны быть в состоянии назвать его любым аргументом, как это:

fObj(7); 

Что явно не подходит для fStr.

+0

+1. Классический. Использование интерфейсов будет работать, но у меня нет доступа к коду. Мне придется переделать мою логику. –

+1

Вам не нужно использовать интерфейсы. У вас просто есть свои задания назад. 'Func ' может быть назначен 'Func ', но не наоборот, из-за того, что первый параметр контравариантен (по ключевому слову). Однако второй параметр является ковариантным (out keyword), что означает, что для 'Func ' может быть присвоено что-то вроде 'Func '. – jam40jeff

0

От MSDN

Implicit conversions: No special syntax is required because the conversion is type safe and no data will be lost. Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

Explicit conversions (casts): Explicit conversions require a cast operator. Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. Typical examples include numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a derived class.

Вы не можете сделать это бросок, потому что вы потеряете информацию. Если вы попытаетесь это по-другому, вы можете сделать это

Func<object, bool> f = ....; 
Func<string, bool> F = f; 

Потому что вы не потеряете информацию.

Простой пример был бы:

// This is ok. you can fit int in double 
int some_int = 42; 
double some_double = some_int; 

// This is not ok. you might lose information 
double some_double_2 = 42; 
int some_int_2 = some_double_2; 


// But you could do this, where the casts says: "Yep, I'm aware I might lose some 
// information, but I'm an UBER programmer and want to do it anyways" 
int some_int_3 = (int)some_double_2; 

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

+2

Этот ответ действительно не затрагивает вопрос о дисперсии 'Func '. Речь идет не о потере информации и не связано с расширением и сужением числовых преобразований. –

4

тип делегата Func<in T, out TResult> явно в первый аргумент типа Tконтравариантен. А «FUNC», который может принимать любой объект может также принимать в строке, так Func<object, X> «является» Func<string, X>, так что это контрвариантность в in типа T.

Вы пытаетесь пойти другим путем. Это будет работать, только если вам известно, что тип времени выполнения - это действительно Func<object, bool>, и вам понадобится явный синтаксис броска, чтобы сообщить компилятору о ваших знаниях. Если тип времени выполнения неверен, явное преобразование не будет выполнено.

Действительный пример:

Func<object, bool> f1 = XXX; 
Func<string, bool> f2 = f1;      // OK, implicit 
Func<object, bool> f3 = (Func<object, bool>)f2; // OK, explicit 
Смежные вопросы