System.Dynamic.ExpandoClass.FindNewClass C# (CSharp) Method

FindNewClass() private method

Finds or creates a new ExpandoClass given the existing set of keys in this ExpandoClass plus the new key to be added. Members in an ExpandoClass are always stored case sensitively.
private FindNewClass ( string newKey ) : ExpandoClass
newKey string
return ExpandoClass
        internal ExpandoClass FindNewClass(string newKey)
        {
            // just XOR the newKey hash code
            int hashCode = _hashCode ^ newKey.GetHashCode();

            lock (this)
            {
                List<WeakReference> infos = GetTransitionList(hashCode);

                for (int i = 0; i < infos.Count; i++)
                {
                    ExpandoClass klass = infos[i].Target as ExpandoClass;
                    if (klass == null)
                    {
                        infos.RemoveAt(i);
                        i--;
                        continue;
                    }

                    if (string.Equals(klass._keys[klass._keys.Length - 1], newKey, StringComparison.Ordinal))
                    {
                        // the new key is the key we added in this transition
                        return klass;
                    }
                }

                // no applicable transition, create a new one
                string[] keys = new string[_keys.Length + 1];
                Array.Copy(_keys, 0, keys, 0, _keys.Length);
                keys[_keys.Length] = newKey;
                ExpandoClass ec = new ExpandoClass(keys, hashCode);

                infos.Add(new WeakReference(ec));
                return ec;
            }
        }

Usage Example

Example #1
0
            /// <summary>
            /// Gets the class and the index associated with the given name.  Does not update the expando object.  Instead
            /// this returns both the original and desired new class.  A rule is created which includes the test for the
            /// original class, the promotion to the new class, and the set/delete based on the class post-promotion.
            /// </summary>
            private ExpandoClass GetClassEnsureIndex(string name, bool caseInsensitive, ExpandoObject obj, out ExpandoClass klass, out int index)
            {
                ExpandoClass originalClass = Value.Class;

                index = originalClass.GetValueIndex(name, caseInsensitive, obj);
                if (index == ExpandoObject.AmbiguousMatchFound)
                {
                    klass = originalClass;
                    return(null);
                }
                if (index == ExpandoObject.NoMatch)
                {
                    // go ahead and find a new class now...
                    ExpandoClass newClass = originalClass.FindNewClass(name);

                    klass = newClass;
                    index = newClass.GetValueIndexCaseSensitive(name);

                    Debug.Assert(index != ExpandoObject.NoMatch);
                    return(originalClass);
                }
                else
                {
                    klass = originalClass;
                    return(null);
                }
            }