Сохранить делегаты функции

#c# #casting #func

#c# #Кастинг #функция

Вопрос:

Я застрял на проблеме. Я обнаружил, что нет неявного преобразования из Func<int> в Func<object> , а затем особенно не из generic Func<T> . Я вроде понимаю, почему нет преобразования. Но мне все еще нужно сохранить любые функции, подобные следующим:

 static Dictionary<int, Func<int, object>> funcs = new Dictionary<int, Func<int, object>>();
public static void SetFunction<T>(Func<int, T> f)
{
    funcs[42] = f;
}

public static void Main()
{
    SetFunction(x => 42);
    SetFunction(x => "42");
    SetFunction(x => Guid.NewGuid());
}
  

Есть ли какой-либо способ сохранить эти функции? Я не хочу использовать dynamic .
Также мне нужно сохранить оригинальные функции. Вызывать их несколько раз.

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

1. Func<TResult> имеет ковариантный возвращаемый тип, Dictionary<TKey, TValue> является инвариантным

2. public static void SetFunction(Func<object> f) {...}

3. @HansPassant, это другой вариант, если вам разрешено изменять API.

4. Я не могу изменить API. Я должен сохранить общий.

Ответ №1:

Вы все равно не смогли бы использовать dynamic , это не то, для чего это нужно. Вместо того, чтобы думать о приведении, просто добавьте еще один слой к вашей функции:

 public static void SetFunction<T>(Func<T> f)
{
    funcs[42] = () => (object)f();
}
  

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

1. Нет, я этого не делаю. Не стесняйтесь отслеживать это, если хотите.

2. dynamic сработало бы в void SetFunction(Func<int, dynamic> f) { funcs[42] = f; } , хотя в этом нет особого смысла Func<int, object> .

Ответ №2:

Вероятно, вы можете вообще избежать использования дженериков.

 static Dictionary<int, Func<object>> funcs = new Dictionary<int, Func<object>>();

public static void SetFunction(Func<object> f)
{
    funcs[42] = f;
}

public static void Main()
{
    SetFunction(() => 42);
    SetFunction(() => "42");
    SetFunction(() => Guid.NewGuid());
}
  

Ответ №3:

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

 static Dictionary<int, Func<object>> funcs = new Dictionary<int, Func<object>>();
static Random rnd = new Random();
public static void SetFunction<T>(int index, Func<Random, T> f)
{
    funcs[index] = () => (object)f(rnd);
}

public static void Main()
{
    SetFunction(41, x => x.NextDouble());
    SetFunction(42, x => x.Next());
    SetFunction(43, _ => "HW");
    Console.WriteLine(funcs[41]());
    Console.WriteLine(funcs[41]());
    Console.WriteLine(funcs[42]());
    Console.WriteLine(funcs[42]());
    Console.WriteLine(funcs[43]());
    Console.WriteLine(funcs[43]());
}
  

Вывод:

 0.6657498062894446
0.5739200415899605
1762534382
1301357548
HW
HW