diff --git a/src/NHibernate.Test/NHSpecificTest/NH3964/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH3964/Fixture.cs new file mode 100644 index 00000000000..22b449d2e2b --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3964/Fixture.cs @@ -0,0 +1,18 @@ +using System.Collections; +using NHibernate.Util; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH3964 +{ + [TestFixture] + public class Fixture + { + [Test(Description = "Test for removal of a workaround for an old Fx bug ( ArrayHelper.AddAll(a2, a1)); + } + } +} \ No newline at end of file diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index 001f3e9c63e..15eeedd2cbd 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -742,6 +742,7 @@ + diff --git a/src/NHibernate/Bytecode/EmitUtil.cs b/src/NHibernate/Bytecode/EmitUtil.cs index 4a73a594ba5..ff615ef90c2 100644 --- a/src/NHibernate/Bytecode/EmitUtil.cs +++ b/src/NHibernate/Bytecode/EmitUtil.cs @@ -2,6 +2,8 @@ using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; +using NHibernate.Linq; +using NHibernate.Util; namespace NHibernate.Bytecode { @@ -185,28 +187,24 @@ public static System.Type DefineDelegateType( public static void EmitLoadType(ILGenerator il, System.Type type) { il.Emit(OpCodes.Ldtoken, type); - il.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle")); + il.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); } public static void EmitLoadMethodInfo(ILGenerator il, MethodInfo methodInfo) { il.Emit(OpCodes.Ldtoken, methodInfo); - il.Emit( - OpCodes.Call, - typeof(MethodBase).GetMethod( - "GetMethodFromHandle", new System.Type[] {typeof(RuntimeMethodHandle)})); + il.Emit(OpCodes.Call, ReflectionCache.MethodBaseMethods.GetMethodFromHandle); il.Emit(OpCodes.Castclass, typeof(MethodInfo)); } + private static readonly MethodInfo CreateDelegate = ReflectionHelper.GetMethod( + () => Delegate.CreateDelegate(null, null)); + public static void EmitCreateDelegateInstance(ILGenerator il, System.Type delegateType, MethodInfo methodInfo) { - MethodInfo createDelegate = typeof(Delegate).GetMethod( - "CreateDelegate", BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, - new System.Type[] {typeof(System.Type), typeof(MethodInfo)}, null); - EmitLoadType(il, delegateType); EmitLoadMethodInfo(il, methodInfo); - il.EmitCall(OpCodes.Call, createDelegate, null); + il.EmitCall(OpCodes.Call, CreateDelegate, null); il.Emit(OpCodes.Castclass, delegateType); } } diff --git a/src/NHibernate/Bytecode/Lightweight/ReflectionOptimizer.cs b/src/NHibernate/Bytecode/Lightweight/ReflectionOptimizer.cs index c50a63fc71e..64c5d88a760 100644 --- a/src/NHibernate/Bytecode/Lightweight/ReflectionOptimizer.cs +++ b/src/NHibernate/Bytecode/Lightweight/ReflectionOptimizer.cs @@ -2,6 +2,7 @@ using System.Reflection.Emit; using System.Security; using System.Security.Permissions; +using NHibernate.Linq; using NHibernate.Properties; using NHibernate.Util; @@ -118,6 +119,9 @@ private static void EmitCastToReference(ILGenerator il, System.Type type) } } + private static readonly MethodInfo GetterCallbackInvoke = ReflectionHelper.GetMethod( + g => g.Invoke(null, 0)); + /// /// Generates a dynamic method on the given type. /// @@ -163,8 +167,7 @@ private GetPropertyValuesInvoker GenerateGetPropertyValuesMethod(IGetter[] gette else { // using the getter itself via a callback - MethodInfo invokeMethod = typeof (GetterCallback).GetMethod("Invoke", - new[] {typeof (object), typeof (int)}); + MethodInfo invokeMethod = GetterCallbackInvoke; il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i); @@ -182,6 +185,9 @@ private GetPropertyValuesInvoker GenerateGetPropertyValuesMethod(IGetter[] gette return (GetPropertyValuesInvoker) method.CreateDelegate(typeof (GetPropertyValuesInvoker)); } + private static readonly MethodInfo SetterCallbackInvoke = ReflectionHelper.GetMethod( + g => g.Invoke(null, 0, null)); + /// /// Generates a dynamic method on the given type. /// @@ -224,8 +230,7 @@ private SetPropertyValuesInvoker GenerateSetPropertyValuesMethod(ISetter[] sette else { // using the setter itself via a callback - MethodInfo invokeMethod = typeof (SetterCallback).GetMethod("Invoke", - new[] {typeof (object), typeof (int), typeof (object)}); + MethodInfo invokeMethod = SetterCallbackInvoke; il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i); diff --git a/src/NHibernate/Linq/DefaultQueryProvider.cs b/src/NHibernate/Linq/DefaultQueryProvider.cs index 432fee40f6a..6ca8dc25846 100644 --- a/src/NHibernate/Linq/DefaultQueryProvider.cs +++ b/src/NHibernate/Linq/DefaultQueryProvider.cs @@ -79,17 +79,13 @@ protected virtual NhLinqExpression PrepareQuery(Expression expression, out IQuer return nhLinqExpression; } + private static readonly MethodInfo Future = ReflectionHelper.GetMethodDefinition(q => q.Future()); + private static readonly MethodInfo FutureValue = ReflectionHelper.GetMethodDefinition(q => q.FutureValue()); + protected virtual object ExecuteFutureQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery) { - MethodInfo method; - if (nhLinqExpression.ReturnType == NhLinqExpressionReturnType.Sequence) - { - method = typeof (IQuery).GetMethod("Future").MakeGenericMethod(nhQuery.Type); - } - else - { - method = typeof (IQuery).GetMethod("FutureValue").MakeGenericMethod(nhQuery.Type); - } + var method = (nhLinqExpression.ReturnType == NhLinqExpressionReturnType.Sequence ? Future : FutureValue) + .MakeGenericMethod(nhQuery.Type); object result = method.Invoke(query, new object[0]); diff --git a/src/NHibernate/Linq/NhRelinqQueryParser.cs b/src/NHibernate/Linq/NhRelinqQueryParser.cs index 4e3b04f04e1..14d1cca760c 100644 --- a/src/NHibernate/Linq/NhRelinqQueryParser.cs +++ b/src/NHibernate/Linq/NhRelinqQueryParser.cs @@ -53,18 +53,26 @@ public NHibernateNodeTypeProvider() { var methodInfoRegistry = new MethodInfoBasedNodeTypeRegistry(); - methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("Fetch") }, typeof(FetchOneExpressionNode)); - methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("FetchMany") }, typeof(FetchManyExpressionNode)); - methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("ThenFetch") }, typeof(ThenFetchOneExpressionNode)); - methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("ThenFetchMany") }, typeof(ThenFetchManyExpressionNode)); + methodInfoRegistry.Register( + new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.Fetch(null, null)) }, + typeof(FetchOneExpressionNode)); + methodInfoRegistry.Register( + new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.FetchMany(null, null)) }, + typeof(FetchManyExpressionNode)); + methodInfoRegistry.Register( + new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.ThenFetch(null, null)) }, + typeof(ThenFetchOneExpressionNode)); + methodInfoRegistry.Register( + new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.ThenFetchMany(null, null)) }, + typeof(ThenFetchManyExpressionNode)); methodInfoRegistry.Register( new[] - { - typeof(LinqExtensionMethods).GetMethod("Cacheable"), - typeof(LinqExtensionMethods).GetMethod("CacheMode"), - typeof(LinqExtensionMethods).GetMethod("CacheRegion"), - }, typeof(CacheableExpressionNode)); + { + ReflectionHelper.GetMethodDefinition(() => LinqExtensionMethods.Cacheable(null)), + ReflectionHelper.GetMethodDefinition(() => LinqExtensionMethods.CacheMode(null, CacheMode.Normal)), + ReflectionHelper.GetMethodDefinition(() => LinqExtensionMethods.CacheRegion(null, null)), + }, typeof(CacheableExpressionNode)); methodInfoRegistry.Register( new[] diff --git a/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs b/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs index 9bbd47fa330..dae61148f78 100644 --- a/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs +++ b/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs @@ -18,12 +18,19 @@ public class ExpressionParameterVisitor : ExpressionTreeVisitor private readonly Dictionary _parameters = new Dictionary(); private readonly ISessionFactoryImplementor _sessionFactory; + private static readonly MethodInfo QueryableSkipDefinition = + ReflectionHelper.GetMethodDefinition(() => Queryable.Skip(null, 0)); + private static readonly MethodInfo QueryableTakeDefinition = + ReflectionHelper.GetMethodDefinition(() => Queryable.Take(null, 0)); + private static readonly MethodInfo EnumerableSkipDefinition = + ReflectionHelper.GetMethodDefinition(() => Enumerable.Skip(null, 0)); + private static readonly MethodInfo EnumerableTakeDefinition = + ReflectionHelper.GetMethodDefinition(() => Enumerable.Take(null, 0)); + private readonly ICollection _pagingMethods = new HashSet { - ReflectionHelper.GetMethodDefinition(() => Queryable.Skip(null, 0)), - ReflectionHelper.GetMethodDefinition(() => Queryable.Take(null, 0)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.Skip(null, 0)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.Take(null, 0)), + QueryableSkipDefinition, QueryableTakeDefinition, + EnumerableSkipDefinition, EnumerableTakeDefinition }; public ExpressionParameterVisitor(ISessionFactoryImplementor sessionFactory) diff --git a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs index 34bc97ec63c..9d1de474209 100644 --- a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs +++ b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs @@ -1,19 +1,23 @@ using System.Linq; +using System.Reflection; using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors { - public class ProcessFirst : ProcessFirstOrSingleBase, IResultOperatorProcessor - { - public void Process(FirstResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) - { - var firstMethod = resultOperator.ReturnDefaultWhenEmpty - ? ReflectionHelper.GetMethodDefinition(() => Queryable.FirstOrDefault(null)) - : ReflectionHelper.GetMethodDefinition(() => Queryable.First(null)); + public class ProcessFirst : ProcessFirstOrSingleBase, IResultOperatorProcessor + { + private static readonly MethodInfo FirstOrDefault = + ReflectionHelper.GetMethodDefinition(() => Queryable.FirstOrDefault(null)); + private static readonly MethodInfo First = + ReflectionHelper.GetMethodDefinition(() => Queryable.First(null)); - AddClientSideEval(firstMethod, queryModelVisitor, tree); + public void Process(FirstResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) + { + var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? FirstOrDefault : First; - tree.AddTakeClause(tree.TreeBuilder.Constant(1)); - } - } + AddClientSideEval(firstMethod, queryModelVisitor, tree); + + tree.AddTakeClause(tree.TreeBuilder.Constant(1)); + } + } } \ No newline at end of file diff --git a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSingle.cs b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSingle.cs index 6e7966914cb..494469a3e32 100644 --- a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSingle.cs +++ b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSingle.cs @@ -1,17 +1,21 @@ using System.Linq; +using System.Reflection; using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors { - public class ProcessSingle : ProcessFirstOrSingleBase, IResultOperatorProcessor - { - public void Process(SingleResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) - { - var firstMethod = resultOperator.ReturnDefaultWhenEmpty - ? ReflectionHelper.GetMethodDefinition(() => Queryable.SingleOrDefault(null)) - : ReflectionHelper.GetMethodDefinition(() => Queryable.Single(null)); + public class ProcessSingle : ProcessFirstOrSingleBase, IResultOperatorProcessor + { + private static readonly MethodInfo SingleOrDefault = + ReflectionHelper.GetMethodDefinition(() => Queryable.SingleOrDefault(null)); + private static readonly MethodInfo Single = + ReflectionHelper.GetMethodDefinition(() => Queryable.Single(null)); - AddClientSideEval(firstMethod, queryModelVisitor, tree); - } - } + public void Process(SingleResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) + { + var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? SingleOrDefault : Single; + + AddClientSideEval(firstMethod, queryModelVisitor, tree); + } + } } \ No newline at end of file diff --git a/src/NHibernate/Proxy/DynamicProxy/DefaultMethodEmitter.cs b/src/NHibernate/Proxy/DynamicProxy/DefaultMethodEmitter.cs index 10449185a78..a7ddb2a04c0 100644 --- a/src/NHibernate/Proxy/DynamicProxy/DefaultMethodEmitter.cs +++ b/src/NHibernate/Proxy/DynamicProxy/DefaultMethodEmitter.cs @@ -10,6 +10,8 @@ using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; +using NHibernate.Linq; +using NHibernate.Util; namespace NHibernate.Proxy.DynamicProxy { @@ -17,13 +19,9 @@ internal class DefaultMethodEmitter : IMethodBodyEmitter { private static readonly MethodInfo getInterceptor; - private static readonly MethodInfo getGenericMethodFromHandle = typeof (MethodBase).GetMethod("GetMethodFromHandle", - BindingFlags.Public | BindingFlags.Static, null, - new[] {typeof (RuntimeMethodHandle), typeof (RuntimeTypeHandle)}, null); - - private static readonly MethodInfo getMethodFromHandle = typeof (MethodBase).GetMethod("GetMethodFromHandle", new[] {typeof (RuntimeMethodHandle)}); - private static readonly MethodInfo getTypeFromHandle = typeof(System.Type).GetMethod("GetTypeFromHandle"); - private static readonly MethodInfo handlerMethod = typeof (IInterceptor).GetMethod("Intercept"); + private static readonly MethodInfo handlerMethod = ReflectionHelper.GetMethod( + i => i.Intercept(null)); + private static readonly MethodInfo getArguments = typeof(InvocationInfo).GetMethod("get_Arguments"); private static readonly ConstructorInfo infoConstructor = typeof (InvocationInfo).GetConstructor(new[] { @@ -118,7 +116,6 @@ private static void EmitBaseMethodCall(ILGenerator IL, MethodInfo method) private static void SaveRefArguments(ILGenerator IL, ParameterInfo[] parameters) { // Save the arguments returned from the handler method - MethodInfo getArguments = typeof (InvocationInfo).GetMethod("get_Arguments"); IL.Emit(OpCodes.Ldloc_1); IL.Emit(OpCodes.Call, getArguments); IL.Emit(OpCodes.Stloc_0); @@ -192,11 +189,11 @@ private static void PushTargetMethodInfo(ILGenerator IL, MethodBuilder generated if (declaringType.IsGenericType) { IL.Emit(OpCodes.Ldtoken, declaringType); - IL.Emit(OpCodes.Call, getGenericMethodFromHandle); + IL.Emit(OpCodes.Call, ReflectionCache.MethodBaseMethods.GetMethodFromHandleWithDeclaringType); } else { - IL.Emit(OpCodes.Call, getMethodFromHandle); + IL.Emit(OpCodes.Call, ReflectionCache.MethodBaseMethods.GetMethodFromHandle); } IL.Emit(OpCodes.Castclass, typeof(MethodInfo)); @@ -232,7 +229,7 @@ private void PushGenericArguments(MethodInfo method, ILGenerator IL) IL.Emit(OpCodes.Dup); IL.Emit(OpCodes.Ldc_I4, index); IL.Emit(OpCodes.Ldtoken, currentType); - IL.Emit(OpCodes.Call, getTypeFromHandle); + IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Stelem_Ref); } } diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs index 9ec0cbfc2f6..8bc6679bfa8 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs @@ -12,21 +12,21 @@ using System.Reflection; using System.Reflection.Emit; using System.Runtime.Serialization; +using NHibernate.Linq; +using NHibernate.Util; namespace NHibernate.Proxy.DynamicProxy { public sealed class ProxyFactory { private static readonly ConstructorInfo defaultBaseConstructor = typeof(object).GetConstructor(new System.Type[0]); - private static readonly MethodInfo getTypeFromHandle = typeof(System.Type).GetMethod("GetTypeFromHandle"); - private static readonly MethodInfo getValue = typeof (SerializationInfo).GetMethod("GetValue", BindingFlags.Public | BindingFlags.Instance, null, - new[] { typeof(string), typeof(System.Type) }, null); - - private static readonly MethodInfo setType = typeof(SerializationInfo).GetMethod("SetType", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(System.Type) }, null); - - private static readonly MethodInfo addValue = typeof (SerializationInfo).GetMethod("AddValue", BindingFlags.Public | BindingFlags.Instance, null, - new[] {typeof (string), typeof (object)}, null); + private static readonly MethodInfo getValue = ReflectionHelper.GetMethod( + si => si.GetValue(null, null)); + private static readonly MethodInfo setType = ReflectionHelper.GetMethod( + si => si.SetType(null)); + private static readonly MethodInfo addValue = ReflectionHelper.GetMethod( + si => si.AddValue(null, null)); public ProxyFactory() : this(new DefaultyProxyMethodBuilder()) {} @@ -221,7 +221,7 @@ private static void ImplementGetObjectData(System.Type baseType, System.Type[] b // info.SetType(typeof(ProxyObjectReference)); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Ldtoken, typeof (ProxyObjectReference)); - IL.Emit(OpCodes.Call, getTypeFromHandle); + IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Callvirt, setType); // info.AddValue("__interceptor", __interceptor); @@ -276,7 +276,7 @@ private static void DefineSerializationConstructor(TypeBuilder typeBuilder, Fiel IL.Emit(OpCodes.Ldtoken, typeof (IInterceptor)); - IL.Emit(OpCodes.Call, getTypeFromHandle); + IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle); IL.Emit(OpCodes.Stloc, interceptorType); IL.Emit(OpCodes.Ldarg_0); diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs index 1cb6db295f5..e97f2426354 100644 --- a/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs +++ b/src/NHibernate/Proxy/DynamicProxy/ProxyImplementor.cs @@ -18,6 +18,9 @@ internal class ProxyImplementor MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual; + private static readonly MethodInfo OriginalSetter = typeof(IProxy).GetMethod("set_Interceptor"); + private static readonly MethodInfo OriginalGetter = typeof(IProxy).GetMethod("get_Interceptor"); + private FieldBuilder field; public FieldBuilder InterceptorField @@ -54,11 +57,8 @@ public void ImplementProxy(TypeBuilder typeBuilder) IL.Emit(OpCodes.Stfld, field); IL.Emit(OpCodes.Ret); - MethodInfo originalSetter = typeof (IProxy).GetMethod("set_Interceptor"); - MethodInfo originalGetter = typeof (IProxy).GetMethod("get_Interceptor"); - - typeBuilder.DefineMethodOverride(setterMethod, originalSetter); - typeBuilder.DefineMethodOverride(getterMethod, originalGetter); + typeBuilder.DefineMethodOverride(setterMethod, OriginalSetter); + typeBuilder.DefineMethodOverride(getterMethod, OriginalGetter); } } } \ No newline at end of file diff --git a/src/NHibernate/Type/TypeFactory.cs b/src/NHibernate/Type/TypeFactory.cs index 4a95b4dba19..acd2495f288 100644 --- a/src/NHibernate/Type/TypeFactory.cs +++ b/src/NHibernate/Type/TypeFactory.cs @@ -3,14 +3,15 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; +using System.Runtime.CompilerServices; using System.Xml; using System.Xml.Linq; using NHibernate.Bytecode; using NHibernate.Classic; +using NHibernate.Linq; using NHibernate.SqlTypes; using NHibernate.UserTypes; using NHibernate.Util; -using System.Runtime.CompilerServices; namespace NHibernate.Type { @@ -37,7 +38,25 @@ private enum TypeClassification private static readonly char[] PrecisionScaleSplit = new[] { '(', ')', ',' }; private static readonly char[] LengthSplit = new[] { '(', ')' }; private static readonly TypeFactory Instance; - private static readonly System.Type[] GenericCollectionSimpleSignature = new[] { typeof(string), typeof(string), typeof(bool) }; + + private static readonly MethodInfo BagDefinition = ReflectionHelper.GetMethodDefinition( + f => f.Bag(null, null, false)); + private static readonly MethodInfo IdBagDefinition = ReflectionHelper.GetMethodDefinition( + f => f.IdBag(null, null, false)); + private static readonly MethodInfo ListDefinition = ReflectionHelper.GetMethodDefinition( + f => f.List(null, null, false)); + private static readonly MethodInfo MapDefinition = ReflectionHelper.GetMethodDefinition( + f => f.Map(null, null, false)); + private static readonly MethodInfo SortedListDefinition = ReflectionHelper.GetMethodDefinition( + f => f.SortedList(null, null, false, null)); + private static readonly MethodInfo SortedDictionaryDefinition = ReflectionHelper.GetMethodDefinition( + f => f.SortedDictionary(null, null, false, null)); + private static readonly MethodInfo SetDefinition = ReflectionHelper.GetMethodDefinition( + f => f.Set(null, null, false)); + private static readonly MethodInfo SortedSetDefinition = ReflectionHelper.GetMethodDefinition( + f => f.SortedSet(null, null, false, null)); + private static readonly MethodInfo OrderedSetDefinition = ReflectionHelper.GetMethodDefinition( + f => f.OrderedSet(null, null, false)); /* * Maps the string representation of the type to the IType. The string @@ -767,80 +786,65 @@ public static CollectionType Array(string role, string propertyRef, bool embedde public static CollectionType GenericBag(string role, string propertyRef, System.Type elementClass) { - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("Bag", new[] {elementClass}, - GenericCollectionSimpleSignature); + MethodInfo mi = BagDefinition.MakeGenericMethod(new[] { elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } public static CollectionType GenericIdBag(string role, string propertyRef, System.Type elementClass) { - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("IdBag", new[] { elementClass }, - GenericCollectionSimpleSignature); + MethodInfo mi = IdBagDefinition.MakeGenericMethod(new[] { elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } public static CollectionType GenericList(string role, string propertyRef, System.Type elementClass) { - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("List", new[] { elementClass }, - GenericCollectionSimpleSignature); + MethodInfo mi = ListDefinition.MakeGenericMethod(new[] { elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } - public static CollectionType GenericMap(string role, string propertyRef, System.Type indexClass, - System.Type elementClass) + public static CollectionType GenericMap(string role, string propertyRef, System.Type indexClass, System.Type elementClass) { - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("Map", new[] {indexClass, elementClass }, - GenericCollectionSimpleSignature); + MethodInfo mi = MapDefinition.MakeGenericMethod(new[] { indexClass, elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } public static CollectionType GenericSortedList(string role, string propertyRef, object comparer, - System.Type indexClass, System.Type elementClass) + System.Type indexClass, System.Type elementClass) { - var signature = new[] { typeof(string), typeof(string), typeof(bool), typeof(IComparer<>).MakeGenericType(indexClass) }; - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("SortedList", new[] { indexClass, elementClass }, - signature); + MethodInfo mi = SortedListDefinition.MakeGenericMethod(new[] { indexClass, elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false, comparer }); } public static CollectionType GenericSortedDictionary(string role, string propertyRef, object comparer, - System.Type indexClass, System.Type elementClass) + System.Type indexClass, System.Type elementClass) { - var signature = new[] { typeof(string), typeof(string), typeof(bool), typeof(IComparer<>).MakeGenericType(indexClass) }; - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("SortedDictionary", new[] { indexClass, elementClass }, - signature); + MethodInfo mi = SortedDictionaryDefinition.MakeGenericMethod(new[] { indexClass, elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false, comparer }); } public static CollectionType GenericSet(string role, string propertyRef, System.Type elementClass) { - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("Set", new[] { elementClass }, - GenericCollectionSimpleSignature); + MethodInfo mi = SetDefinition.MakeGenericMethod(new[] { elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } - public static CollectionType GenericSortedSet(string role, string propertyRef, object comparer, - System.Type elementClass) + public static CollectionType GenericSortedSet(string role, string propertyRef, object comparer, System.Type elementClass) { - var signature = new[] { typeof(string), typeof(string), typeof(bool), typeof(IComparer<>).MakeGenericType(elementClass) }; - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("SortedSet", new[] { elementClass }, - signature); + MethodInfo mi = SortedSetDefinition.MakeGenericMethod(new[] { elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false, comparer }); } - public static CollectionType GenericOrderedSet(string role, string propertyRef, - System.Type elementClass) + public static CollectionType GenericOrderedSet(string role, string propertyRef, System.Type elementClass) { - MethodInfo mi = ReflectHelper.GetGenericMethodFrom("OrderedSet", new[] { elementClass }, - GenericCollectionSimpleSignature); + MethodInfo mi = OrderedSetDefinition.MakeGenericMethod(new[] { elementClass }); return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } diff --git a/src/NHibernate/Util/ArrayHelper.cs b/src/NHibernate/Util/ArrayHelper.cs index 395e0c792d8..8bab75868bd 100644 --- a/src/NHibernate/Util/ArrayHelper.cs +++ b/src/NHibernate/Util/ArrayHelper.cs @@ -95,40 +95,9 @@ public static string ToString(object[] array) /// public static void AddAll(IList to, IList from) { - System.Action addNull = null; foreach (object obj in from) { - // There is bug in .NET, before version 4, where adding null to a List> through the non-generic IList interface throws an exception. - // TODO: Everything but the to.Add(obj) should be conditionally compiled only for versions of .NET earlier than 4. - if (obj == null) - { - if (addNull == null) - { - var toType = to.GetType(); - if (toType.IsGenericType && - toType.GetGenericTypeDefinition() == typeof(List<>) && - toType.GetGenericArguments()[0].IsNullable()) - { - MethodInfo addMethod = toType.GetMethod("Add"); - var addMethodCall = System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression.Constant(to), - addMethod, - System.Linq.Expressions.Expression.Constant(null, toType.GetGenericArguments()[0])); - System.Linq.Expressions.LambdaExpression addLambda = - System.Linq.Expressions.Expression.Lambda(addMethodCall); - - addNull = (System.Action)addLambda.Compile(); - } - else - { - addNull = () => to.Add(null); - } - } - addNull(); - } - else - { - to.Add(obj); - } + to.Add(obj); } } diff --git a/src/NHibernate/Util/ReflectHelper.cs b/src/NHibernate/Util/ReflectHelper.cs index 8814f780fe3..64536f9617e 100644 --- a/src/NHibernate/Util/ReflectHelper.cs +++ b/src/NHibernate/Util/ReflectHelper.cs @@ -565,6 +565,7 @@ internal static object GetConstantValue(string qualifiedName, ISessionFactoryImp return null; } + [Obsolete("Please use Linq.ReflectionHelper instead")] public static MethodInfo GetGenericMethodFrom(string methodName, System.Type[] genericArgs, System.Type[] signature) { MethodInfo result = null; diff --git a/src/NHibernate/Util/ReflectionCache.cs b/src/NHibernate/Util/ReflectionCache.cs index 8cd4a94253c..767a17d0b8b 100644 --- a/src/NHibernate/Util/ReflectionCache.cs +++ b/src/NHibernate/Util/ReflectionCache.cs @@ -16,6 +16,7 @@ internal static class ReflectionCache // - If the method is generic, suffix it with "On" followed by its generic parameter type names. // Avoid caching here narrow cases, such as those using specific types and unlikely to be used by many classes. // Cache them instead in classes using them. + internal static class EnumerableMethods { internal static readonly MethodInfo AggregateDefinition = @@ -40,5 +41,19 @@ internal static class EnumerableMethods internal static readonly MethodInfo ToListDefinition = ReflectionHelper.GetMethodDefinition(() => Enumerable.ToList(null)); } + + internal static class MethodBaseMethods + { + internal static readonly MethodInfo GetMethodFromHandle = + ReflectionHelper.GetMethod(() => MethodBase.GetMethodFromHandle(new RuntimeMethodHandle())); + internal static readonly MethodInfo GetMethodFromHandleWithDeclaringType = + ReflectionHelper.GetMethod(() => MethodBase.GetMethodFromHandle(new RuntimeMethodHandle(), new RuntimeTypeHandle())); + } + + internal static class TypeMethods + { + internal static readonly MethodInfo GetTypeFromHandle = + ReflectionHelper.GetMethod(() => System.Type.GetTypeFromHandle(new RuntimeTypeHandle())); + } } } \ No newline at end of file