Как бросить лямбды?
Я хотел бы, чтобы семейство функций хранилось в словаре, который был получен из некоторого базового типа (например, вызывается базовый класс "объект" ). Таким образом, можно сохранить f1 в f2?
Func<bool> f1 = () => true;
Func<object> f2 = f1;
Ошибка 1 Невозможно неявно преобразовать тип System.Func<bool>
в System.Func<object>
Это лучшее, что мы можем сделать?
Func<bool> f1 = () => true;
Func<object> f2 = () => (object)f1;
Ошибки: (нет)
Я предполагаю, что он должен быть универсальным дружественным - это утверждение where... но я не уверен, что вы можете сделать это с помощью lamdas.
Следуя за информацией Армена, я вникнул в определения string и bool:
public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable,
IComparable<String>, IEnumerabl<char>,
IEquatable<String>
public struct Boolean : IComparable, IConvertible, IComparable<Boolean>,
IEquatable<Boolean>
Он имеет право на значение ref Vs. Строит ли строка из объекта неявно? Похоже, это поведение для структур в соответствии с ссылкой @PeterK.
"ValueType переопределяет виртуальные методы из Object с более соответствующие реализации для типов значений. См. Также Enum, который наследует от ValueType."
Объект:
System.Object: все классы, структуры, перечисления и делегаты. (от http://msdn.microsoft.com/en-us/library/system.object)
Это, в свою очередь, делает Func<bool>
недоступным для Func<object>
немного тупым. то есть иерархия наследования была правильна с этой точки зрения.
Ответы
Ответ 1
От здесь (внимание мое):
Covariance позволяет использовать более производный тип, чем тот, который задан общим параметром. Это позволяет неявное преобразование классов, которые реализуют варианты интерфейсов и неявное преобразование типов делегатов. Ковариантность и контравариантность поддерживаются для ссылочных типов , но они не поддерживаются для типов значений.
Также:
Отклонение применяется только к ссылочным типам; если вы укажете тип значения для параметра типа варианта, этот тип параметра является инвариантным для результирующего построенного типа.
Причина может быть связана с тем, как С# и CLI исторически имеют дело (и не согласны) с ковариацией массива типов значений. Посмотрите здесь для некоторой информации.
Итак, вы видите, что ковариация параметра типа в Func<out TResult>
не работает со значениями типов, поэтому вы должны это сделать:
Func<object> f2 = () => f1();
Ответ 2
Если вы используете .NET 4.0+, это возможно.
Ваш пример не работает, потому что bool - это тип значения. Однако, если вы хотите изменить bool со строкой, образец работает.
Func<string> f1 = () => "true";
Func<object> f2 = f1;