SetValueDirect() private method

private SetValueDirect ( TypedReference obj, Object value ) : void
obj TypedReference
value Object
return void
示例#1
0
        /*===============================DoValueTypeFixup===============================
        **Arguments:
        ** memberToFix -- the member in the object contained in holder being fixed up.
        ** holder -- the ObjectHolder for the object (a value type in this case) being completed.
        ** value  -- the data to set into the field.
        ==============================================================================*/
        private bool DoValueTypeFixup(FieldInfo memberToFix, ObjectHolder holder, object value)
        {
            var fieldsTemp = new FieldInfo[4];
            FieldInfo[] fields = null;
            int currentFieldIndex = 0;
            int[] arrayIndex = null;
            ValueTypeFixupInfo currFixup = null;
            object fixupObj = holder.ObjectValue;
            ObjectHolder originalHolder = holder;

            Debug.Assert(holder != null, "[TypedReferenceBuilder.ctor]holder!=null");
            Debug.Assert(holder.RequiresValueTypeFixup, "[TypedReferenceBuilder.ctor]holder.RequiresValueTypeFixup");

            //In order to get a TypedReference, we need to get a list of all of the FieldInfos to 
            //create the path from our outermost containing object down to the actual field which
            //we'd like to set.  This loop is used to build up that list.
            while (holder.RequiresValueTypeFixup)
            {
                //Enlarge the array if required (this is actually fairly unlikely as it would require that we
                //be nested more than 4 deep.
                if ((currentFieldIndex + 1) >= fieldsTemp.Length)
                {
                    var temp = new FieldInfo[fieldsTemp.Length * 2];
                    Array.Copy(fieldsTemp, 0, temp, 0, fieldsTemp.Length);
                    fieldsTemp = temp;
                }

                //Get the fixup information.  If we have data for our parent field, add it to our list
                //and continue the walk up to find the next outermost containing object.  We cache the 
                //object that we have.  In most cases, we could have just grabbed it after this loop finished.
                //However, if the outermost containing object is an array, we need the object one further
                //down the chain, so we have to do a lot of caching.
                currFixup = holder.ValueFixup;
                fixupObj = holder.ObjectValue;  //Save the most derived 
                if (currFixup.ParentField != null)
                {
                    FieldInfo parentField = currFixup.ParentField;

                    ObjectHolder tempHolder = FindObjectHolder(currFixup.ContainerID);
                    if (tempHolder.ObjectValue == null)
                    {
                        break;
                    }
                    if (Nullable.GetUnderlyingType(parentField.FieldType) != null)
                    {
                        fieldsTemp[currentFieldIndex] = parentField.FieldType.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance);
                        currentFieldIndex++;
                    }

                    fieldsTemp[currentFieldIndex] = parentField;
                    holder = tempHolder;
                    currentFieldIndex++;
                }
                else
                {
                    //If we find an index into an array, save that information.
                    Debug.Assert(currFixup.ParentIndex != null, "[ObjectManager.DoValueTypeFixup]currFixup.ParentIndex!=null");
                    holder = FindObjectHolder(currFixup.ContainerID); //find the array to fix.
                    arrayIndex = currFixup.ParentIndex;
                    break;
                }
            }

            //If the outermost container isn't an array, we need to grab it.  Otherwise, we just need to hang onto
            //the boxed object that we already grabbed.  We'll assign the boxed object back into the array as the
            //last step.
            if (!(holder.ObjectValue is Array) && holder.ObjectValue != null)
            {
                fixupObj = holder.ObjectValue;
                Debug.Assert(fixupObj != null, "[ObjectManager.DoValueTypeFixup]FixupObj!=null");
            }

            if (currentFieldIndex != 0)
            {
                //MakeTypedReference requires an array of exactly the correct size that goes from the outermost object
                //in to the innermost field.  We currently have an array of arbitrary size that goes from the innermost
                //object outwards.  We create an array of the right size and do the copy.
                fields = new FieldInfo[currentFieldIndex];
                for (int i = 0; i < currentFieldIndex; i++)
                {
                    FieldInfo fieldInfo = fieldsTemp[(currentFieldIndex - 1 - i)];
                    fields[i] = fieldInfo;
                }

                Debug.Assert(fixupObj != null, "[ObjectManager.DoValueTypeFixup]fixupObj!=null");
                //Make the TypedReference and use it to set the value.
                TypedReference typedRef = TypedReference.MakeTypedReference(fixupObj, fields);
                if (memberToFix != null)
                {
                    memberToFix.SetValueDirect(typedRef, value);
                }
                else
                {
                    TypedReference.SetTypedReference(typedRef, value);
                }
            }
            else if (memberToFix != null)
            {
                FormatterServices.SerializationSetValue(memberToFix, fixupObj, value);
            }

            //If we have an array index, it means that our outermost container was an array.  We don't have
            //any way to build a TypedReference into an array, so we'll use the array functions to set the value.
            if (arrayIndex != null && holder.ObjectValue != null)
            {
                ((Array)(holder.ObjectValue)).SetValue(fixupObj, arrayIndex);
            }

            return true;
        }
示例#2
0
	public static void set_field_of_expanded (object root_object, FieldInfo [] a_fields, FieldInfo a_field, object val)
		// Set `a_field' with `val', an attribute reachable from `root_object' using `a_fields' as a path to
		// reach it.
	{
		TypedReference t = TypedReference.MakeTypedReference(root_object, a_fields);
		a_field.SetValueDirect(t, val);
	}