private void AssertValueTypeConverts <T>(params T[] values) where T : struct
        {
            // Common factory should detect and return nullable converter
            ArgumentValueConverter <T> converter = ArgumentValueConverter.CreateValueConverter <T>();

            Assert.AreEqual(typeof(ArgumentValueConverter.ValueTypeConverter <T>), converter.GetType(), "Did not create a pass through converter");

            // Loop over the sample values
            foreach (T value in values)
            {
                T result = converter.ConvertFrom(value);
                Assert.AreEqual(value, result, "Passthrough<" + typeof(T).Name + " failed to convert");
            }

            // A null should convert to default(T)
            object valueFromNull = converter.ConvertFrom(null);

            Assert.IsNotNull(valueFromNull, "Value type conversion from null cannot be null");
            Assert.AreEqual(default(T), valueFromNull, "Value type conversion from null should be default(T)");

            ExceptionAssert.ThrowsInvalidOperation(
                "Attempting to convert a string to a value type should throw",
                () => converter.ConvertFrom("hello")
                );
        }
        private void AssertReferenceTypeConverts <T>(params T[] values)
        {
            // Common factory should detect and return nullable converter
            ArgumentValueConverter <T> converter = ArgumentValueConverter.CreateValueConverter <T>();

            Assert.AreEqual(typeof(ArgumentValueConverter.ReferenceTypeConverter <T>), converter.GetType(), "Did not create a pass through converter");

            T result;

            // Loop over the sample values
            foreach (T value in values)
            {
                result = converter.ConvertFrom(value);
                Assert.AreEqual(value, result, "Passthrough<" + typeof(T).Name + " failed to convert");
            }

            // A reference type should be able to convert null
            result = converter.ConvertFrom(null);
            Assert.IsNull(result, "Converting reference type " + typeof(T).Name + " failed to convert null");
        }
        private void AssertNullableConverts <T>(params T[] values) where T : struct
        {
            // Common factory should detect and return nullable converter
            ArgumentValueConverter <Nullable <T> > converter = ArgumentValueConverter.CreateValueConverter <Nullable <T> >();
            //Assert.AreEqual(typeof(ArgumentValueConverter.NullableConverter<Nullable<T>>), converter.GetType(), "Did not create a nullable converter");

            // A clean null should convert
            Nullable <T> result = converter.ConvertFrom(null);

            Assert.IsFalse(result.HasValue, "Nullable<" + typeof(T).Name + "> null should convert to nullable with HasValue==false");

            // A default(T) should convert
            result = converter.ConvertFrom(default(T));
            Assert.IsTrue(result.HasValue, "default(" + typeof(T).Name + ") should convert to nullable with HasValue==true");
            Assert.AreEqual(default(T), result.Value, "default(" + typeof(T).Name + ") did not convert correctly");

            // Loop over the sample values
            foreach (T value in values)
            {
                // The underlying type should be convertable
                result = converter.ConvertFrom(value);
                Assert.IsTrue(result.HasValue, "Nullable<" + typeof(T).Name + "> value should convert to nullable with HasValue==true");
                Assert.AreEqual(value, result.Value, "Nullable<" + typeof(T).Name + "> expected value to convert correctly");

                // A nullable of the underlying type should be convertable
                Nullable <T> nullableOfT = new Nullable <T>(value);
                result = converter.ConvertFrom(nullableOfT);
                Assert.IsTrue(result.HasValue, "Nullable<" + typeof(T).Name + "> value should convert to Nullable<T> with HasValue==true");
                Assert.AreEqual(nullableOfT, result, "Nullable<" + typeof(T).Name + "> expected Nullable<T> value to convert correctly");
            }

            // Object of the wrong type should throw
            ExceptionAssert.ThrowsInvalidOperation(
                "Asking NullableConverter to convert wrong type should throw",
                () => converter.ConvertFrom(new object())
                );
        }