Linq重载where子句以排除特定类型

时间:2012-10-01 15:23:30

标签: linq methods dictionary where

我正在实现一个以TKey作为参数返回IDictionary<TKey, TValue>的扩展方法。如果TValuedouble,则该方法可能会返回具有最高值的TKey。否则,它将随机返回TKey

    public static TKey Sample<TKey>(this IDictionary<TKey, double> probabilityTable, Random r)
    {
        probabilityTable.Normalize();

        var roll = r.NextDouble();
        var temp = 0.0;
        foreach (var key in probabilityTable.Keys)
        {
            temp += probabilityTable[key];
            if (roll <= temp)
                return key;
        }

        return default(TKey);
    }

    public static TKey Sample<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, Random r)
    {
        return dictionary.Skip(r.Next(dictionary.Count)).FirstOrDefault().Key;
    }

    public static IDictionary<TKey, double> Normalize<TKey>(this IDictionary<TKey, double> probabilityTable)
    {
        if (probabilityTable.Any(x => x.Value < 0))
            throw new ArgumentOutOfRangeException("probabilityTable", "Probability is expected to be positive.");

        var sum = probabilityTable.Sum(x => x.Value);

        if (Math.Abs(sum - 1) > 1e-8)
            return probabilityTable.ToDictionary(x => x.Key, x => x.Value / sum);

        if (Math.Abs(sum) < 1e-8)
            return probabilityTable.ToDictionary(x => x.Key, x => 1.0 / probabilityTable.Count);

        return probabilityTable;
    }

问题是即使Sample<TKey, TValue> double TValue,也始终会调用TValue。我可以指定类型where TValue: !double的任何方式使用where子句排除double?即 var r = new Random(); var pt = new Dictionary<char, double> {{'A', 0.1}, {'B', 0.2}, {'C', 0.7}}; var ct = new Dictionary<char, char> {{'A', 'D'}, {'B','E'}, {'C', 'F'}}; Console.WriteLine(pt.Sample(r)); // expected to return 'C' mostly but uniformly returns key Console.WriteLine(ct.Sample(r));

调用扩展函数的代码如下:

{{1}}

1 个答案:

答案 0 :(得分:0)

约束不是签名的一部分,也许以下链接可以帮助您:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

相关问题