From 5d3bf14a5017f7f00e1f89f90a79231bbe6602f3 Mon Sep 17 00:00:00 2001 From: Daniel Redondo Date: Tue, 23 Jun 2020 10:51:15 +0200 Subject: [PATCH] Allows override a protected method in the proxy --- .../DuckType.Methods.cs | 14 ++++++----- .../Wanhjor.ObjectInspector.csproj | 2 +- .../DuckTypeAbstractTests.cs | 24 ++++++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/Wanhjor.ObjectInspector/DuckType.Methods.cs b/src/Wanhjor.ObjectInspector/DuckType.Methods.cs index f3651d0..0c2040a 100644 --- a/src/Wanhjor.ObjectInspector/DuckType.Methods.cs +++ b/src/Wanhjor.ObjectInspector/DuckType.Methods.cs @@ -22,9 +22,9 @@ private static List GetMethods(Type baseType) return selectedMethods; static IEnumerable GetBaseMethods(Type baseType) { - foreach (var method in baseType.GetMethods()) + foreach (var method in baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { - if (method.IsSpecialName || method.DeclaringType == typeof(DuckType)) + if (method.IsSpecialName || method.IsFinal || method.IsPrivate || method.DeclaringType == typeof(DuckType)) continue; if (baseType.IsInterface || method.IsAbstract || method.IsVirtual) yield return method; @@ -40,6 +40,11 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in var iMethodParameters = iMethod.GetParameters(); var iMethodParametersTypes = iMethodParameters.Select(p => p.ParameterType).ToArray(); + // We select the method to call + var method = SelectMethod(instanceType, iMethod, iMethodParameters, iMethodParametersTypes); + if (method is null && iMethod.IsVirtual) + continue; + var attributes = iMethod.IsAbstract || iMethod.IsVirtual ? MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig : MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot; @@ -66,14 +71,11 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in var il = methodBuilder.GetILGenerator(); var publicInstance = instanceType.IsPublic || instanceType.IsNestedPublic; - // We select the method to call - var method = SelectMethod(instanceType, iMethod, iMethodParameters, iMethodParametersTypes); - if (method is null) { il.Emit(OpCodes.Newobj, typeof(NotImplementedException).GetConstructor(Type.EmptyTypes)!); il.Emit(OpCodes.Throw); - return; + continue; } var innerDuck = false; diff --git a/src/Wanhjor.ObjectInspector/Wanhjor.ObjectInspector.csproj b/src/Wanhjor.ObjectInspector/Wanhjor.ObjectInspector.csproj index e41d5ed..fd64dae 100644 --- a/src/Wanhjor.ObjectInspector/Wanhjor.ObjectInspector.csproj +++ b/src/Wanhjor.ObjectInspector/Wanhjor.ObjectInspector.csproj @@ -6,7 +6,7 @@ An efficient .NET object inspector/accesor to avoid reflection usage with duck typing support. 8 enable - 0.4.0-beta.3 + 0.4.0-beta.4 true ObjectInspector Daniel Redondo diff --git a/test/Wanhjor.ObjectInspector.Tests/DuckTypeAbstractTests.cs b/test/Wanhjor.ObjectInspector.Tests/DuckTypeAbstractTests.cs index 962d097..8c54a59 100644 --- a/test/Wanhjor.ObjectInspector.Tests/DuckTypeAbstractTests.cs +++ b/test/Wanhjor.ObjectInspector.Tests/DuckTypeAbstractTests.cs @@ -132,6 +132,8 @@ public void ReverseDuckTest() var name = duck.GetName(); Assert.Equal("From Base", name); + + var value = duck.GetValue(); } } @@ -151,7 +153,17 @@ public abstract class AbstractDuckTestNoInherits public abstract string Name { get; set; } } - public abstract class ReverseDuck + public abstract class ReverseDuckBase : IDisposable + { + public abstract string GetValue(); + + public void Dispose() + { + + } + } + + public abstract class ReverseDuck : ReverseDuckBase { public string Name { get; set; } = "From Base"; @@ -162,6 +174,11 @@ public string GetValues() return $"{Name} => {Value}"; } + public override string GetValue() + { + return string.Empty; + } + public abstract string GetName(); } @@ -179,6 +196,11 @@ public string GetName() { return _extractor.Name; } +/* + public string GetValue() + { + return Value; + }*/ public void SetProxyObject(object proxy) {