public void StaticPropertyGetter1WorksWithBoxing()
        {
            var property = typeof(Garply).GetProperty(nameof(Garply.Baz));

            var getter = new StaticPropertyGetter <IBaz>(property);

            getter.Func.Target.Should().BeSameAs(getter);
            getter.Func.Method.Name.Should().Be(nameof(getter.GetValueReflection));
            getter.Func.Method.DeclaringType.Should().Be(typeof(StaticPropertyGetter <IBaz>));

            var  reflectionTimer = Stopwatch.StartNew();
            IBaz reflectionValue = getter.GetValue();

            reflectionTimer.Stop();

            getter.SetOptimizedFunc();

            getter.Func.Target.Should().NotBeSameAs(getter);
            getter.Func.Method.Name.Should().Be(StaticPropertyGetter.GetStaticValueOptimized);
            getter.Func.Method.DeclaringType.Should().NotBe(typeof(StaticPropertyGetter <IBaz>));

            var  optimizedTimer = Stopwatch.StartNew();
            IBaz optimizedValue = getter.GetValue();

            optimizedTimer.Stop();

            optimizedValue.Should().Be(reflectionValue);
            optimizedTimer.Elapsed.Should().BeLessThan(reflectionTimer.Elapsed);
        }
        /// <summary>
        /// Creates a function that gets the value of the specified static property.
        /// </summary>
        /// <param name="property">The static property to create the getter function for.</param>
        /// <returns>A function that gets the static property value.</returns>
        public static Func <object> CreateStaticGetter(this PropertyInfo property)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }
            if (!property.CanRead || !property.GetMethod.IsPublic)
            {
                throw new ArgumentException("Property must have public getter.", nameof(property));
            }
            if (!property.GetMethod.IsStatic)
            {
                throw new ArgumentException("Property must be static.", nameof(property));
            }

            var getter = new StaticPropertyGetter(property);

            QueueUserWorkItem(getter, g => g.SetOptimizedFunc());
            return(getter.GetValue);
        }
        /// <summary>
        /// Creates a function that gets the value of the specified static property.
        /// </summary>
        /// <typeparam name="TPropertyType">
        /// The return type of the resulting function. This type must be compatible with the
        /// <see cref="PropertyInfo.PropertyType"/> of the <paramref name="property"/> parameter.
        /// </typeparam>
        /// <param name="property">The static property to create the getter function for.</param>
        /// <returns>A function that gets the static property value.</returns>
        public static Func <TPropertyType> CreateStaticGetter <TPropertyType>(this PropertyInfo property)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }
            if (!typeof(TPropertyType).IsAssignableFrom(property.PropertyType))
            {
                throw new ArgumentException("TPropertyType must be assignable from property.PropertyType", nameof(property));
            }
            if (!property.CanRead || !property.GetMethod.IsPublic)
            {
                throw new ArgumentException("property must have public getter", nameof(property));
            }
            if (!property.GetMethod.IsStatic)
            {
                throw new ArgumentException("Property must be static.", nameof(property));
            }

            var getter = new StaticPropertyGetter <TPropertyType>(property);

            QueueUserWorkItem(getter, g => g.SetOptimizedFunc());
            return(getter.GetValue);
        }
 static public void BindPropertyCallback(StaticPropertyGetter staticGetter, StaticPropertySetter staticSetter, InstancePropertyGetter instanceGetter, InstancePropertySetter instanceSetter)
 {
     General_Typescript_Class_BindPropertyCallback(staticGetter, staticSetter, instanceGetter, instanceSetter);
 }
 static private extern void General_Typescript_Class_BindPropertyCallback(StaticPropertyGetter staticGetter, StaticPropertySetter staticSetter, InstancePropertyGetter instanceGetter, InstancePropertySetter instanceSetter);