GetAccessPath() public static method

Gets the series of properties that needs to be accessed to access a logical item in a potentially nested tuple.
public static GetAccessPath ( Type tupleType, int index ) : IEnumerable
tupleType System.Type
index int
return IEnumerable
Exemplo n.º 1
0
        public void VerifyTuple(int size)
        {
            //Construct a tuple of the right type
            MethodInfo mi = typeof(MutableTuple).GetMethod("MakeTupleType", BindingFlags.Public | BindingFlags.Static);

            Assert(mi != null, "Could not find Tuple.MakeTupleType");

            Type[]   args   = new Type[size];
            object[] values = new object[size];
            for (int i = 0; i < size; i++)
            {
                args[i]   = typeof(int);
                values[i] = 0;
            }

            Type         tupleType = (Type)mi.Invoke(null, new object[] { args });
            MutableTuple t         = MutableTuple.MakeTuple(tupleType, values);

            /////////////////////
            //Properties

            //Write
            for (int i = 0; i < size; i++)
            {
                object o = t;
                foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, i))
                {
                    if (typeof(MutableTuple).IsAssignableFrom(pi.PropertyType))
                    {
                        o = pi.GetValue(o, null);
                    }
                    else
                    {
                        pi.SetValue(o, i * 5, null);
                    }
                }
            }

            //Read
            for (int i = 0; i < size; i++)
            {
                object o = t;
                foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, i))
                {
                    o = pi.GetValue(o, null);
                }
                AreEqual(typeof(int), o.GetType());
                AreEqual((int)o, i * 5);
            }

            //Negative cases for properties
            AssertError <ArgumentException>(delegate() {
                foreach (PropertyInfo pi in MutableTuple.GetAccessPath(tupleType, -1))
                {
                    Console.WriteLine(pi.Name); //This won't run, but we need it so that this call isn't inlined
                }
            });

            /////////////////////
            //GetTupleValues
            values = MutableTuple.GetTupleValues(t);
            AreEqual(values.Length, size);
            for (int i = 0; i < size; i++)
            {
                AreEqual(typeof(int), values[i].GetType());
                AreEqual((int)(values[i]), i * 5);
            }

            /////////////////////
            //Access methods

            if (size <= MutableTuple.MaxSize)
            {
                //SetValue
                for (int i = 0; i < size; i++)
                {
                    t.SetValue(i, i * 3);
                }

                //GetValue
                for (int i = 0; i < size; i++)
                {
                    AreEqual(t.GetValue(i), i * 3);
                }

                //Ensure there are no extras
                if (tupleType.GetGenericArguments().Length <= size)
                {
                    //We're requesting an index beyond the end of this tuple.
                    AssertError <ArgumentException>(delegate() { t.SetValue(size, 3); });
                    AssertError <ArgumentException>(delegate() { t.GetValue(size); });
                }
                else
                {
                    /*We're requesting an index in the scope of this tuple but beyond the scope of our
                     * requested capacity (in which case the field's type will be Microsoft.Scripting.None
                     * and we won't be able to convert "3" to that).  Imagine asking for a tuple of 3 ints,
                     * we'd actually get a Tuple<int,int,int,Microsoft.Scripting.None> since there is no
                     * Tuple that takes only 3 generic arguments.*/
                    AssertError <InvalidCastException>(delegate() { t.SetValue(size, 3); });

                    //Verify the type of the field
                    AreEqual(typeof(Microsoft.Scripting.Runtime.DynamicNull), tupleType.GetGenericArguments()[size]);

                    //Verify the value of the field is null
                    AreEqual(null, t.GetValue(size));
                }
            }
        }