Concurrent Dictionary AddOrUpdate方法的第三个参数是什么?

8
private readonly ConcurrentDictionary<string, System.Drawing.Color> _colorSet;      

public void BuildColorSet(IList<string> colorNames, string prefix, bool forceLastToGray)
{
    var size = forceLastToGray ? colorNames.Count - 1 : colorNames.Count;

    int nbHue = 6;
    int nbCycle = (int)Math.Ceiling((double)size / nbHue);

    var saturationMax = nbCycle <= 2 ? 1.0 : 1.0;
    var saturationMin = 0.3;
    var luminanceMax = nbCycle <= 2 ? 0.85 : 0.85;
    var luminanceMin = 0.3;
    var maxSaturationShift = 0.30;
    var maxLuminanceShift = 0.15;

    var interval = 1.0 / Math.Min(size, nbHue);

    var saturationShift = (saturationMax - saturationMin) / (nbCycle - 1);
    saturationShift = Math.Min(saturationShift, maxSaturationShift);
    var luminanceShift = (luminanceMax - luminanceMin) / (nbCycle - 1);
    luminanceShift = Math.Min(luminanceShift, maxLuminanceShift);

    var hueShift = 0.0;

    var saturation = saturationMax;
    var luminance = luminanceMax;
    for(var i = 0; i<size; i++)
    {
        if(i > 0 && (i % nbHue == 0)) // Next Cycle
        {
            saturation -= saturationShift;
            luminance -= luminanceShift;
            hueShift = hueShift == 0 ? interval/2 : 0;
        }
        var hue = interval*(i%nbHue) + hueShift;

        System.Drawing.Color color = HSL2RGB(hue, saturation, luminance);

    _colorSet.AddOrUpdate(prefix + colorNames[i], color, ???);
    }
    if(forceLastToGray)
    {
        _colorSet.TryAdd(prefix + colorNames[colorNames.Count - 1], System.Drawing.Color.LightGray);
    }

    _cssDirty = true;
}

如果颜色存在,我希望能够使用新值更新字典。如果字典中没有这种颜色,也要将其添加到字典中。
我正在使用AddOrUpdate方法,但是无法获得该方法的第三个参数(来自lambda表达式或委托方法)。
请问我的第三个参数应该是什么样子的?


我不知道你在问什么。你有查看文档吗?http://msdn.microsoft.com/en-us/library/ee378665.aspx - asawyer
你在 AddOrUpdate 中看到了 "???" 吗?那是我缺少的参数。有什么想法可以组成那个参数吗? - Ruruboy
1
是的 - 请阅读文档。 - asawyer
_colorSet.AddOrUpdate(prefix + colorNames[i], color, (colorNames[i], _colorSet) => { _colorSet.TryAdd(prefix + colorNames[i], color); return _colorSet; }); - Ruruboy
我尝试了,但它无法构建。我做错了什么? - Ruruboy
这是一篇关于ConcurrentDictionary的不错博客文章,可能比API文档更易读:http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx - Rory
3个回答

24

根据文档:

updateValueFactory 类型: System.Func 用于基于现有键的现有值生成新值的函数。

如果集合中已经存在该值,则保持该值不变:

_colorSet.AddOrUpdate(prefix + colorNames[i], color,
            (key, existingVal) =>
            {
                return existingVal;
            });

这将使用插入时指定的相同值替换集合中的值:

_colorSet.AddOrUpdate(prefix + colorNames[i], color,
            (key, existingVal) =>
            {
                return color;
            });

例如,您可以在函数中执行条件逻辑、旧值和新值之间的比较,或更新原始对象。

_colorSet.AddOrUpdate(prefix + colorNames[i], color,
            (key, existingVal) =>
            {
                if (existingVal.Name == "Red")
                    return existingVal;
                else
                    return color;
            });

ConcurrentDictionary 中的键是 prefix + colorNames[i],值为 System.Drawing.Color。你有什么想法,key 和 existingVal 会是什么? - Ruruboy
"key" 将是与该键匹配的现有项的键,因此值等于前缀 + colorNames[i]。existingValue 将是字典中已经存在于键:prefix + colorNames[i] 的 System.Drawing.Color 对象。因此,在您的情况下,key 是一个字符串,existingVal 是一个 System.Drawing.Color。数据类型是基于您声明 ConcurrentDictionary 对象变量的泛型数据类型。 - ulty4life

1
根据asawyer给你的网页,所需的是一个函数。
Func<TKey, TValue, TValue>

在这种情况下,看起来您正在传递一个字符串和一个颜色,但是如何组合它们在很大程度上取决于您。您需要一个返回颜色的函数,因此从语法角度来看,以下内容应该可以工作。
(key, oldValue) => oldValue

我不知道你是如何计算新值的。例如,您可以使用您的新颜色。

_colorSet.AddOrUpdate(prefix + colorNames[i], color, (key, oldValue) => color); 

字符串是键,颜色是值。你有想法这个表达式会是什么吗?我的意思是 (key, oldValue) => color。 - Ruruboy

0

看起来你并不关心颜色是否已经存在;你总是想要更新字典中的值。在这种情况下,最好使用普通的索引器,例如

_colorSet[prefix + colorNames[i]] = color;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接