I have implemented a LCG IGetSetHelper implementation. It needs to be tested (and I don't really have the time to manage it). So here it is...
Code:
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Cfg/Environment.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Cfg/Environment.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Cfg/Environment.cs   (revision 92)
@@ -94,8 +94,10 @@
       public const string PrepareSql = "hibernate.prepare_sql";
       public const string CommandTimeout = "hibernate.command_timeout";
       public const string PropertyUseReflectionOptimizer = "hibernate.use_reflection_optimizer";
+        public const string PropertyUseLightweightCodeGeneration = "hibernate.use_lightweight_code_generation";
 
       private static bool EnableReflectionOptimizer;
+        private static bool EnableLightweightCodeGeneration;
 
       private static IDictionary GlobalProperties;
 
@@ -191,5 +193,14 @@
          get { return EnableReflectionOptimizer; }
          set { EnableReflectionOptimizer = value; }
       }
+
+        /// <summary>
+        /// Enables the use of .NET 2.0 LCG techniques within the reflection optimizer.
+        /// </summary>
+        public static bool UseLightweightCodeGeneration
+        {
+            get { return EnableLightweightCodeGeneration; }
+            set { EnableLightweightCodeGeneration = value; }
+        }
    }
 }
\ No newline at end of file
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/ISetter.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/ISetter.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/ISetter.cs   (revision 92)
@@ -40,5 +40,16 @@
       /// <id> property.
       /// </remarks>
       PropertyInfo Property { get; }
+
+        /// <summary>
+        /// Gets the member info of the underlying member that this getter wraps. 
+        /// Should return null when not implemented.
+        /// </summary>
+        MemberInfo Member { get; }
+
+        /// <summary>
+        /// Gets the type of the property/field.
+        /// </summary>
+        System.Type ValueType { get; }
    }
 }
\ No newline at end of file
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/BasicGetter.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/BasicGetter.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/BasicGetter.cs   (revision 92)
@@ -75,6 +75,10 @@
          get { return property; }
       }
 
+        public MemberInfo Member
+        {
+            get { return property; }
+        }
       #endregion
    }
 }
\ No newline at end of file
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/FieldGetter.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/FieldGetter.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/FieldGetter.cs   (revision 92)
@@ -73,6 +73,10 @@
          get { return null; }
       }
 
+        public MemberInfo Member
+        {
+            get { return field; }
+        }
       #endregion
    }
 }
\ No newline at end of file
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/IGetter.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/IGetter.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/IGetter.cs   (revision 92)
@@ -48,5 +48,11 @@
       /// <id> property.
       /// </remarks>
       PropertyInfo Property { get; }
+
+        /// <summary>
+        /// Gets the member info of the underlying member that this getter wraps. 
+        /// Should return null when not implemented.
+        /// </summary>
+        MemberInfo Member { get; }
    }
 }
\ No newline at end of file
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/BasicSetter.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/BasicSetter.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/BasicSetter.cs   (revision 92)
@@ -81,6 +81,15 @@
          get { return property; }
       }
 
+        public MemberInfo Member
+        {
+            get { return property; }
+        }
+
+        public System.Type ValueType
+        {
+            get { return property.PropertyType; }
+        }
       #endregion
    }
 }
\ No newline at end of file
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/FieldSetter.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/FieldSetter.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Property/FieldSetter.cs   (revision 92)
@@ -81,6 +81,15 @@
          get { return null; }
       }
 
+        public MemberInfo Member
+        {
+            get { return field; }
+        }
+
+        public System.Type ValueType
+        {
+            get { return field.FieldType; }
+        }
       #endregion
    }
 
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Persister/LCGGetSetHelper.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Persister/LCGGetSetHelper.cs   (revision 0)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Persister/LCGGetSetHelper.cs   (revision 92)
@@ -0,0 +1,243 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Globalization;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using log4net;
+using NHibernate.Property;
+
+namespace NHibernate.Persister
+{
+    class LCGGetSetHelper : IGetSetHelper
+    {
+        private delegate void SetPropertyValuesInvoker(object o,object[] values);
+        private delegate object[] GetPropertyValuesInvoker(object o);
+
+        private SetPropertyValuesInvoker m_Setter;
+        private GetPropertyValuesInvoker m_Getter;
+
+        private static readonly ILog m_Log = LogManager.GetLogger(typeof(LCGGetSetHelper));
+
+        /// <summary>
+        /// Class constructor.
+        /// </summary>
+        /// <param name="mappedClass"></param>
+        /// <param name="setters"></param>
+        /// <param name="getters"></param>
+        public LCGGetSetHelper(System.Type mappedClass, ISetter[] setters, IGetter[] getters)
+        {
+            //Generate the set and get dynamic methods
+            m_Setter = GenerateSetPropertyValuesMethod(mappedClass, setters);
+            m_Getter = GenerateGetPropertyValuesMethod(mappedClass, getters);
+        }
+
+        /// <summary>
+        /// Generates a dynamic method on the given type.
+        /// </summary>
+        /// <param name="mappedClass"></param>
+        /// <param name="getters"></param>
+        /// <returns></returns>
+        private static GetPropertyValuesInvoker GenerateGetPropertyValuesMethod(System.Type mappedClass, IGetter[] getters)
+        {
+            DynamicMethod method = new DynamicMethod(
+                String.Empty, 
+                typeof(object[]), 
+                new System.Type[] { typeof(object) }, 
+                mappedClass, 
+                true);
+
+            ILGenerator il = method.GetILGenerator();
+
+            // Declare the locals
+            LocalBuilder dataLocal = il.DeclareLocal(typeof(Object[]));
+            LocalBuilder thisLocal = il.DeclareLocal(mappedClass);
+
+            // Set the this local
+            il.Emit(OpCodes.Ldarg_0);
+            il.Emit(OpCodes.Stloc, thisLocal.LocalIndex);
+
+            // Allocate the data array
+            il.Emit(OpCodes.Ldc_I4, getters.Length);
+            il.Emit(OpCodes.Newarr, typeof(Object));
+            il.Emit(OpCodes.Stloc, dataLocal.LocalIndex);
+
+            //get all the data from the object into the data array to be returned
+            for (int i = 0; i < getters.Length; i++)
+            {
+                // get the member accessors
+                IGetter getter = getters[i];
+                if (getter.Member != null)
+                {
+                    // get the data element location
+                    il.Emit(OpCodes.Ldloc, dataLocal.LocalIndex);
+                    il.Emit(OpCodes.Ldc_I4, i);
+
+                    // get the value
+                    il.Emit((mappedClass.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc), thisLocal.LocalIndex);
+                    switch (getter.Member.MemberType)
+                    {
+                        // fields...
+                        case MemberTypes.Field:
+                            FieldInfo fieldInfo = ((FieldInfo)getter.Member);
+                            il.Emit(OpCodes.Ldfld, fieldInfo);
+                            break;
+
+                        // properties...
+                        case MemberTypes.Property:
+                            MethodInfo methodInfo = ((PropertyInfo)getter.Member).GetGetMethod(true);
+                            if (methodInfo != null)
+                            {
+                                if (methodInfo.IsVirtual)
+                                {
+                                    il.Emit(OpCodes.Callvirt, methodInfo);
+                                }
+                                else
+                                {
+                                    il.Emit(OpCodes.Call, methodInfo);
+                                }
+                            }
+                            else
+                            {
+                                m_Log.InfoFormat("Property {0} is marked write-only. Retrieving null value.", getter.PropertyName);
+                                il.Emit(OpCodes.Pop);
+                                il.Emit(OpCodes.Ldnull);
+                            }
+                            break;
+
+                        // uh-oh!
+                        default:
+                            throw new NHibernate.HibernateException("Unhandled member type!");
+                    }
+
+                    // box the value?
+                    if (getter.ReturnType.IsValueType)
+                    {
+                        il.Emit(OpCodes.Box, getter.ReturnType);
+                    }
+                }
+                else
+                {
+                    throw new NHibernate.HibernateException("IGetter implementation does not implement the required Member property!");
+                }
+
+                //store the value
+                il.Emit(OpCodes.Stelem_Ref);
+            }
+
+            // Return the data array
+            il.Emit(OpCodes.Ldloc, dataLocal.LocalIndex);
+            il.Emit(OpCodes.Ret);
+
+            return (GetPropertyValuesInvoker)method.CreateDelegate(typeof(GetPropertyValuesInvoker));
+        }
+
+        /// <summary>
+        /// Generates a dynamic method on the given type.
+        /// </summary>
+        /// <param name="mappedClass"></param>
+        /// <param name="setters"></param>
+        /// <returns></returns>
+        private static SetPropertyValuesInvoker GenerateSetPropertyValuesMethod(System.Type mappedClass, ISetter[] setters)
+        {
+            DynamicMethod method = new DynamicMethod(
+                String.Empty, 
+                typeof(void), 
+                new System.Type[] { typeof(object), typeof(object[]) }, 
+                mappedClass, 
+                true);
+            
+            ILGenerator il = method.GetILGenerator();
+
+            // Declare a local variable used to store the object reference (typed)
+            LocalBuilder thisLocal = il.DeclareLocal(mappedClass);
+            il.Emit(OpCodes.Ldarg_0);
+            il.Emit(OpCodes.Stloc, thisLocal.LocalIndex);
+
+            for (int i = 0; i < setters.Length; i++)
+            {
+                // get the member accessor
+                ISetter setter = setters[i];
+                if (setter.Member != null)
+                {
+                    // load the this pointer
+                    il.Emit((mappedClass.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc), thisLocal.LocalIndex);
+
+                    // load the value
+                    il.Emit(OpCodes.Ldarg_1);
+                    il.Emit(OpCodes.Ldc_I4, i);
+                    il.Emit(OpCodes.Ldelem_Ref);
+
+                    // cast and optionly unbox the value
+                    il.Emit(OpCodes.Unbox_Any, setter.ValueType);
+
+                    // set the value
+                    switch (setter.Member.MemberType)
+                    {
+                        // fields...
+                        case MemberTypes.Field:
+                            il.Emit(OpCodes.Stfld, (FieldInfo)setter.Member);
+                            break;
+
+                        // properties...
+                        case MemberTypes.Property:
+                            MethodInfo methodInfo = ((PropertyInfo)setter.Member).GetSetMethod(true);
+                            if (methodInfo != null)
+                            {
+                                if (methodInfo.IsVirtual)
+                                {
+                                    il.Emit(OpCodes.Callvirt, methodInfo);
+                                }
+                                else
+                                {
+                                    il.Emit(OpCodes.Call, methodInfo);
+                                }
+                            }
+                            else
+                            {
+                                m_Log.InfoFormat("Property {0} is marked read-only. Ignoring property value.", setter.PropertyName);
+                                il.Emit(OpCodes.Pop);
+                                il.Emit(OpCodes.Pop);
+                            }
+                            break;
+
+                        // uh-oh!
+                        default:
+                            throw new NHibernate.HibernateException("Unhandled member type!");
+                    }
+                }
+                else
+                {
+                    throw new NHibernate.HibernateException("ISetter implementation does not implement the required Member property!");
+                }
+            }
+
+            // Setup the return
+            il.Emit(OpCodes.Ret);
+
+            return (SetPropertyValuesInvoker)method.CreateDelegate(typeof(SetPropertyValuesInvoker));
+        }
+
+        /// <summary>
+        /// Sets the property values.
+        /// </summary>
+        /// <param name="o"></param>
+        /// <param name="values"></param>
+        public void SetPropertyValues(object o, object[] values)
+        {
+            m_Setter(o, values);
+        }
+
+        /// <summary>
+        /// Gets the property values.
+        /// </summary>
+        /// <param name="o"></param>
+        /// <returns></returns>
+        public object[] GetPropertyValues(object o)
+        {
+            return m_Getter(o);
+        }
+
+    }
+}
Index: D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Persister/GetSetHelperFactory.cs
===================================================================
--- D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Persister/GetSetHelperFactory.cs   (revision 90)
+++ D:/Acme/3rdParty/NHibernate/1.0.2.0/Support/src/NHibernate/Persister/GetSetHelperFactory.cs   (revision 92)
@@ -53,16 +53,23 @@
       /// <param name="setters">Array of setters</param>
       /// <param name="getters">Array of getters</param>
       /// <returns>null if the generation fail</returns>
-      public static IGetSetHelper Create( System.Type mappedClass, ISetter[] setters, IGetter[] getters )
-      {
-         if (mappedClass.IsValueType)
-         {
-            // Cannot create optimizer for value types - the setter method will not work.
-            log.Info( "Disabling reflection optimizer for value type " + mappedClass.FullName );
-            return null;
-         }
-         return new GetSetHelperFactory( mappedClass, setters, getters ).CreateGetSetHelper();
-      }
+        public static IGetSetHelper Create(System.Type mappedClass, ISetter[] setters, IGetter[] getters)
+        {
+            if (!Cfg.Environment.UseLightweightCodeGeneration)
+            {
+                if (mappedClass.IsValueType)
+                {
+                    // Cannot create optimizer for value types - the setter method will not work.
+                    log.Info("Disabling reflection optimizer for value type " + mappedClass.FullName);
+                    return null;
+                }
+                return new GetSetHelperFactory(mappedClass, setters, getters).CreateGetSetHelper();
+            }
+            else
+            {
+                return new LCGGetSetHelper(mappedClass, setters, getters);
+            }
+        }
 
       private IGetSetHelper CreateGetSetHelper()
       {