[Mono-bugs] [Bug 328036] [PATCH]Casting bug with generic collections

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Tue Sep 25 18:48:43 EDT 2007


Michi Henning <michi at zeroc.com> changed:

           What    |Removed                                         |Added
                 CC|                                                |michi at zeroc.com

--- Comment #8 from Michi Henning <michi at zeroc.com>  2007-09-25 16:48:43 MST ---
(In reply to comment #7 from Robert Jordan)
> I really thought about optimizing this, but I looked like a seldom hit
> corner case to me, because in many cases Key/ValueCollection.CopyTo will
> be called instead of the (hidden) ICollection.CopyTo.

I think the optimization might be worthwhile. For me, this issue arose in the
context of having existing code that uses sequence that are derived from
CollectionBase, and dictionaries that are derived from DictionaryBase. (This is
with Ice--see http://www.zeroc.com)

With C# 2.0, we decided to provide an updated collection mapping that uses
strongly-type containers, such as List<T> and Dictionary<KT, VT>.

Now we need to support both the old and the new mappings, and one of the
requirements is that we need deep equality semantics. Rather than generating
(or requiring the user to write) a separate comparison method for each
strongly-typed collection, I wanted to provide a comparison method that would
work for everthing, both old and new collections. So, for dictionaries, I wrote
the following:

public static bool Equals(System.Collections.IDictionary d1,
                          System.Collections.IDictionary d2)
    bool result;

    // Try to determine equality based on reference equality
    // and number of elements first. This avoids the expensive
    // comparison of all elements.

    if(cheapComparison(d1, d2, out result))
        return result;

    // Need to compare all the entries after all, at O(n^2) cost.

    // Get and sort both sets of keys. Keys are unique and non-null.
    System.Collections.ICollection keys1 = d1.Keys;
    System.Collections.ICollection keys2 = d2.Keys;
    object[] ka1 = new object[d1.Count];
    object[] ka2 = new object[d2.Count];
    keys1.CopyTo(ka1, 0);
    keys2.CopyTo(ka2, 0);

        System.Collections.IEnumerator e = ka2.GetEnumerator();
        foreach(object o in ka1)
                return false;
            if(!Equals(d1[o], d2[o]))
                return false;
        return false;

    return true;

The array copy is necessary because I need to sort the keys, and I'm using the
generic version because, in the Ice run time, I have no idea what the actual
types involved are.

I haven't benchmarked this but, for large dictionaries, I suspect that the
array copy will account for an appreciable fraction of the total time.

Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.

More information about the mono-bugs mailing list