diff --git a/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs b/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs index 1f18e170e8a..722bb604af2 100644 --- a/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs +++ b/src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs @@ -816,6 +816,50 @@ private static BinaryFormatter GetFormatter() #endif } +#if NETCOREAPP3_1_OR_GREATER + public interface IWithStaticMethods + { + // C# 8 + static void StaticMethod() + { + } + +#if NET7_0_OR_GREATER + // C# 11 + static abstract void StaticAbstractMethod(); + + // C# 11 + static virtual void StaticVirtualMethod() + { + } +#endif + } + + public class ClassWithStaticInterfaceMethods : IWithStaticMethods + { + public static void StaticAbstractMethod() + { + } + } + + [Test(Description = "GH3295")] + public void VerifyProxyForClassWithStaticInterfaceMethod() + { + var factory = new StaticProxyFactory(); + factory.PostInstantiate( + typeof(ClassWithStaticInterfaceMethods).FullName, + typeof(ClassWithStaticInterfaceMethods), + new HashSet { typeof(INHibernateProxy) }, + null, null, null, true); + + var proxy = factory.GetProxy(1, null); + Assert.That(proxy, Is.Not.Null); + Assert.That(proxy, Is.InstanceOf()); + + Assert.That(factory.GetFieldInterceptionProxy(), Is.InstanceOf()); + } +#endif + #if NETFX private static void VerifyGeneratedAssembly(System.Action assemblyGenerator) { diff --git a/src/NHibernate/Proxy/ProxyBuilderHelper.cs b/src/NHibernate/Proxy/ProxyBuilderHelper.cs index 64ee3879e67..7f922911616 100644 --- a/src/NHibernate/Proxy/ProxyBuilderHelper.cs +++ b/src/NHibernate/Proxy/ProxyBuilderHelper.cs @@ -21,6 +21,8 @@ namespace NHibernate.Proxy { internal static class ProxyBuilderHelper { + private const BindingFlags ProxiableMethodsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructor(System.Type.EmptyTypes); private static readonly ConstructorInfo SecurityCriticalAttributeConstructor = typeof(SecurityCriticalAttribute).GetConstructor(System.Type.EmptyTypes); private static readonly ConstructorInfo IgnoresAccessChecksToAttributeConstructor = typeof(IgnoresAccessChecksToAttribute).GetConstructor(new[] {typeof(string)}); @@ -94,10 +96,7 @@ internal static void CallDefaultBaseConstructor(ILGenerator il, System.Type pare internal static IEnumerable GetProxiableMethods(System.Type type) { - const BindingFlags candidateMethodsBindingFlags = - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; - - return type.GetMethods(candidateMethodsBindingFlags).Where(m => m.IsProxiable()); + return type.GetMethods(ProxiableMethodsBindingFlags).Where(m => m.IsProxiable()); } internal static IEnumerable GetProxiableMethods(System.Type type, IEnumerable interfaces) @@ -105,12 +104,12 @@ internal static IEnumerable GetProxiableMethods(System.Type type, IE if (type.IsInterface || type == typeof(object) || type.GetInterfaces().Length == 0) { return GetProxiableMethods(type) - .Concat(interfaces.SelectMany(i => i.GetMethods())) + .Concat(interfaces.SelectMany(i => i.GetMethods(ProxiableMethodsBindingFlags))) .Distinct(); } var proxiableMethods = new HashSet(GetProxiableMethods(type), new MethodInfoComparer(type)); - foreach (var interfaceMethod in interfaces.SelectMany(i => i.GetMethods())) + foreach (var interfaceMethod in interfaces.SelectMany(i => i.GetMethods(ProxiableMethodsBindingFlags))) { proxiableMethods.Add(interfaceMethod); }