/// <summary> /// Deletes a property from the schema. /// </summary> /// <param name="name"> The name of the property to delete. </param> /// <returns> A new schema without the property. </returns> public HiddenClassSchema DeleteProperty(string name) { // Check if there is a transition to the schema already. HiddenClassSchema newSchema = null; if (this.m_deleteTransitions != null) { this.m_deleteTransitions.TryGetValue(name, out newSchema); } if (newSchema == null) { // Create a new schema based on this one. var properties = this.m_properties == null?CreatePropertiesDictionary() : new Dictionary <string, SchemaProperty>(this.m_properties); if (properties.Remove(name) == false) { throw new InvalidOperationException(string.Format("The property '{0}' does not exist.", name)); } newSchema = new HiddenClassSchema(properties, this.NextValueIndex); // Add a transition to the new schema. if (this.m_deleteTransitions == null) { this.m_deleteTransitions = new Dictionary <string, HiddenClassSchema>(1); } this.m_deleteTransitions.Add(name, newSchema); } return(newSchema); }
/// <summary> /// Enumerates the property names and values for this schema. /// </summary> /// <param name="values"> The array containing the property values. </param> /// <returns> An enumerable collection of property names and values. </returns> public IEnumerable <PropertyNameAndValue> EnumeratePropertyNamesAndValues(object[] values) { if (this.m_properties == null) { this.m_properties = CreatePropertiesDictionary(); } this.m_parent = null; // Prevents the properties dictionary from being stolen while an enumeration is in progress. return(this.m_properties.Select(pair => new PropertyNameAndValue(pair.Key, new PropertyDescriptor(values[pair.Value.Index], pair.Value.Attributes)))); }
/// <summary> /// Adds a property to the schema. /// </summary> /// <param name="name"> The name of the property to add. </param> /// <param name="attributes"> The property attributes. </param> /// <returns> A new schema with the extra property. </returns> public HiddenClassSchema AddProperty(string name, PropertyAttributes attributes) { // Package the name and attributes into a struct. var transitionInfo = new TransitionInfo { Name = name, Attributes = attributes }; // Check if there is a transition to the schema already. HiddenClassSchema newSchema = null; if (this.m_addTransitions != null) { this.m_addTransitions.TryGetValue(transitionInfo, out newSchema); } if (newSchema == null) { if (this.m_parent == null) { // Create a new schema based on this one. A complete copy must be made of the properties hashtable. var properties = new Dictionary <string, SchemaProperty>(this.m_properties) { { name, new SchemaProperty(this.NextValueIndex, attributes) } }; newSchema = new HiddenClassSchema(properties, this.NextValueIndex + 1, this, transitionInfo); } else { // Create a new schema based on this one. The properties hashtable is "given // away" so a copy does not have to be made. if (this.m_properties == null) { this.m_properties = CreatePropertiesDictionary(); } this.m_properties.Add(name, new SchemaProperty(this.NextValueIndex, attributes)); newSchema = new HiddenClassSchema(this.m_properties, this.NextValueIndex + 1, this, transitionInfo); this.m_properties = null; } // Add a transition to the new schema. if (this.m_addTransitions == null) { this.m_addTransitions = new Dictionary <TransitionInfo, HiddenClassSchema>(1); } this.m_addTransitions.Add(transitionInfo, newSchema); } return(newSchema); }
/// <summary> /// Modifies the attributes for a property in the schema. /// </summary> /// <param name="name"> The name of the property to modify. </param> /// <param name="attributes"> The new attributes. </param> /// <returns> A new schema with the modified property. </returns> public HiddenClassSchema SetPropertyAttributes(string name, PropertyAttributes attributes) { // Package the name and attributes into a struct. var transitionInfo = new TransitionInfo { Name = name, Attributes = attributes }; // Check if there is a transition to the schema already. HiddenClassSchema newSchema = null; if (this.m_modifyTransitions != null) { this.m_modifyTransitions.TryGetValue(transitionInfo, out newSchema); } if (newSchema == null) { // Create the properties dictionary if it hasn't already been created. if (this.m_properties == null) { this.m_properties = CreatePropertiesDictionary(); } // Check the attributes differ from the existing attributes. SchemaProperty propertyInfo; if (this.m_properties.TryGetValue(name, out propertyInfo) == false) { throw new InvalidOperationException(string.Format("The property '{0}' does not exist.", name)); } if (attributes == propertyInfo.Attributes) { return(this); } // Create a new schema based on this one. var properties = new Dictionary <string, SchemaProperty>(this.m_properties); properties[name] = new SchemaProperty(propertyInfo.Index, attributes); newSchema = new HiddenClassSchema(properties, this.NextValueIndex); // Add a transition to the new schema. if (this.m_modifyTransitions == null) { this.m_modifyTransitions = new Dictionary <TransitionInfo, HiddenClassSchema>(1); } this.m_modifyTransitions.Add(transitionInfo, newSchema); } return(newSchema); }
/// <summary> /// Creates a new HiddenClassSchema instance from an add operation. /// </summary> private HiddenClassSchema(Dictionary <string, SchemaProperty> properties, int nextValueIndex, HiddenClassSchema parent, TransitionInfo addPropertyTransitionInfo) : this(properties, nextValueIndex) { this.m_parent = parent; this.m_addPropertyTransitionInfo = addPropertyTransitionInfo; }