public void StaticPropertySetter1Works()
        {
            Baz.Qux = -1;

            var property = typeof(Baz).GetProperty(nameof(Baz.Qux));

            var setter = new StaticPropertySetter <int>(property);

            setter.Action.Target.Should().BeSameAs(setter);
            setter.Action.Method.Name.Should().Be(nameof(setter.SetValueReflection));
            setter.Action.Method.DeclaringType.Should().Be(typeof(StaticPropertySetter <int>));

            var reflectionTimer = Stopwatch.StartNew();

            setter.SetValue(123);
            reflectionTimer.Stop();

            Baz.Qux.Should().Be(123);

            setter.SetOptimizedAction();

            setter.Action.Target.Should().NotBeSameAs(setter);
            setter.Action.Method.Name.Should().Be(StaticPropertySetter.SetStaticValueOptimized);
            setter.Action.Method.DeclaringType.Should().NotBe(typeof(StaticPropertySetter <int>));

            var optimizedTimer = Stopwatch.StartNew();

            setter.SetValue(456);
            optimizedTimer.Stop();

            Baz.Qux.Should().Be(456);

            optimizedTimer.Elapsed.Should().BeLessThan(reflectionTimer.Elapsed);
        }
        /// <summary>
        /// Creates an action that sets the value of the specified static property. The
        /// parameter of the resulting function takes the new value of the static property.
        /// </summary>
        /// <param name="property">The static property to create the setter action for.</param>
        /// <returns>An action that sets the static property value.</returns>
        public static Action <object> CreateStaticSetter(this PropertyInfo property)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }
            if (!property.CanWrite || !property.SetMethod.IsPublic)
            {
                throw new ArgumentException("property must have public setter", nameof(property));
            }
            if (!property.SetMethod.IsStatic)
            {
                throw new ArgumentException("Property must be static.", nameof(property));
            }

            var setter = new StaticPropertySetter(property);

            QueueUserWorkItem(setter, s => s.SetOptimizedAction());
            return(setter.SetValue);
        }
        /// <summary>
        /// Creates an action that sets the value of the specified static property. The
        /// parameter of the resulting function takes the new value of the static property.
        /// </summary>
        /// <typeparam name="TPropertyType">
        /// The type of the parameter of the resulting action. 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 setter action for.</param>
        /// <returns>An action that sets the static property value.</returns>
        public static Action <TPropertyType> CreateStaticSetter <TPropertyType>(this PropertyInfo property)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }
            if (!property.PropertyType.IsAssignableFrom(typeof(TPropertyType)))
            {
                throw new ArgumentException("property.PropertyType must be assignable from TPropertyType", nameof(property));
            }
            if (!property.CanWrite || !property.SetMethod.IsPublic)
            {
                throw new ArgumentException("property must have public setter", nameof(property));
            }
            if (!property.SetMethod.IsStatic)
            {
                throw new ArgumentException("Property must be static.", nameof(property));
            }

            var setter = new StaticPropertySetter <TPropertyType>(property);

            QueueUserWorkItem(setter, s => s.SetOptimizedAction());
            return(setter.SetValue);
        }
 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);