Большинство реализаций Fortran не имеют стандартного способа манипулирования указателями функций или указателями процедур. Тем не менее, Fortran 2003 и более поздние версии имеют что-то. (См. Стр. 6 из этого .)
Для данной ситуации это будет очень хорошо работать на месте:
function func1 (p1, p2, etc)
... as you have it already
end
function func2 (p1, p2, etc)
... as you have it already
end
function funcselect (a, p1, p2, etc)
if (a < 0) then
x = func1 (p1, p2, etc)
else
x = func2 (p1, p2, etc)
endif
end
Затем просто вызовите funcselect
с дополнительным параметром вместо того, что вы бы сделали с loop_func
.
Проблема заключается в классической ковариации / контравариантности дженериков. Вы предполагаете, что поскольку MyDerived1
и MyDerived2
наследуются от MyBase
, то a RetVal<MyDerived1>
наследуется от RetVal<MyBase>
, а это не так.
Самый простой способ исправить это, вероятно, изменить код на:
var list2 = new List<Func<RetVal<MyBase>>>
{
() => (MyBase)test.GetRetValT<MyDerived1>,
() => (MyBase)test.GetRetValT<MyDerived2>
};
или еще лучше, как указывает JS в комментариях, просто измените RetVal<T>
на ковариантный, если это возможно:
public interface IRetVal<out T> { ... }
public class RetVal<T> : IRetVal<T> { ... }