public void CreateStaticSetter1Works()
        {
            var property = typeof(Corge).GetProperty(nameof(Corge.Bar));

            Action <int> setter;
            var          queued = (Callback : (WaitCallback)null, PropertySetter : (StaticPropertySetter <int>)null);

            void queueUserWorkItem(WaitCallback callback, object state) => queued = (callback, (StaticPropertySetter <int>)state);

            PropertyInfoExtensions.SetQueueUserWorkItemAction(queueUserWorkItem);

            try
            {
                setter = property.CreateStaticSetter <int>();
            }
            finally
            {
                PropertyInfoExtensions.SetQueueUserWorkItemAction(null);
            }

            // Verify that a work item was queued
            queued.PropertySetter.Should().NotBeNull();
            queued.Callback.Should().NotBeNull();

            // Verify that the return delegate is correct
            setter.Target.Should().BeSameAs(queued.PropertySetter);
            setter.Method.Name.Should().Be(nameof(StaticPropertySetter <int> .SetValue));
            setter.Method.DeclaringType.Should().Be(typeof(StaticPropertySetter <int>));

            // Verify that the queued Callback calls the SetOptimizedFunc
            // method of the queued PropertySetter.
            var beforeAction = queued.PropertySetter.Action;

            queued.Callback.Invoke(queued.PropertySetter);
            var afterAction = queued.PropertySetter.Action;

            beforeAction.Should().NotBeSameAs(afterAction);
        }
        public void CreateGetter2Works()
        {
            Func <Foo, int> getter;
            var             queued = (Callback : (WaitCallback)null, PropertyGetter : (PropertyGetter <Foo, int>)null);

            void queueUserWorkItem(WaitCallback callback, object state) => queued = (callback, (PropertyGetter <Foo, int>)state);

            PropertyInfoExtensions.SetQueueUserWorkItemAction(queueUserWorkItem);

            try
            {
                getter = _property.CreateGetter <Foo, int>();
            }
            finally
            {
                PropertyInfoExtensions.SetQueueUserWorkItemAction(null);
            }

            // Verify that a work item was queued
            queued.PropertyGetter.Should().NotBeNull();
            queued.Callback.Should().NotBeNull();

            // Verify that the return delegate is correct
            getter.Target.Should().BeSameAs(queued.PropertyGetter);
            getter.Method.Name.Should().Be(nameof(PropertyGetter <Foo, int> .GetValue));
            getter.Method.DeclaringType.Should().Be(typeof(PropertyGetter <Foo, int>));

            // Verify that the queued Callback calls the SetOptimizedFunc
            // method of the queued PropertyGetter.
            var beforeFunc = queued.PropertyGetter.Func;

            queued.Callback.Invoke(queued.PropertyGetter);
            var afterFunc = queued.PropertyGetter.Func;

            beforeFunc.Should().NotBeSameAs(afterFunc);
        }