Я пишу программу winform для тестирования параллельного словаря С# с классом ниже:
public class Class1
{
public int X = 10;
public Class1(int x)
{
X = x;
Debug.WriteLine("Class1 Created");
}
}
и ниже код кнопки:
private void button1_Click(object sender, EventArgs e)
{
var dict = new ConcurrentDictionary<int, Class1>();
Func<Class1> valueFactory = () =>
{
Debug.WriteLine("Factory Called");
return new Class1(5);
};
var temp = dict.GetOrAdd(1, valueFactory());
Debug.WriteLine(temp.X);
temp.X = 20;
var temp2 = dict.GetOrAdd(1, valueFactory());
Debug.WriteLine(temp2.X);
}
Я заметил, что метод valueFactory всегда выполнялся, а конструктор Class1 вызывался дважды, даже если ключ уже существует в dict после первого метода GetorAdd.
Однако, если я изменю определение Func на
Func<int, Class1> valueFactory = (k) =>
{
Debug.WriteLine("Factory Called");
return new Class1(5);
};
и вызовите метод GetorAdd, как показано ниже:
var temp = dict.GetOrAdd(1, valueFactory);
Программа работает так, как нужно, так как во втором вызове не вызывала конструктор Class1. Я подозреваю, что это потому, что я передал делегат valueFactory вместо вызова функции valueFactory()
в метод GetorAdd. Интересно, есть ли подробное объяснение того, что происходит под капотом, и я также не понимаю, почему я не могу не передать valueFactory в качестве делегата, если мое определение Func отличается от Func<int, Class1
(то же определение, что и словарь)
Спасибо.