From 025e6529de4fb1aa1bfd2e95e05e3f597197b73b Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 9 Jul 2019 09:23:41 -0600 Subject: [PATCH] Added CreateOrDefault method to get best default value for a structure. Added InvokeStaticMethod to allow for calling a static method generically. --- Core/Extensions/ReflectionExtensions.cs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/Core/Extensions/ReflectionExtensions.cs b/Core/Extensions/ReflectionExtensions.cs index 346f76a4..a41d254e 100644 --- a/Core/Extensions/ReflectionExtensions.cs +++ b/Core/Extensions/ReflectionExtensions.cs @@ -11,6 +11,15 @@ namespace Vanara.Extensions { private const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase; + /// For a structure, gets either the result of the static Create method or the default. + /// The structure's type. + /// The result of the static Create method or the default. + public static T CreateOrDefault() where T : struct + { + var mi = typeof(T).GetMethod("Create", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, Type.EmptyTypes, null); + return mi == null ? (default) : (T)mi.Invoke(null, null); + } + /// Gets all loaded types in the . /// The application domain. /// All loaded types. @@ -205,6 +214,20 @@ namespace Vanara.Extensions return (T)mi.Invoke(obj, args); } + /// Invokes a named static method of a type with parameters. + /// The expected type of the method's return value. + /// The type containing the static method. + /// Name of the method. + /// The arguments to provide to the method invocation. + /// The value returned from the method. + public static T InvokeStaticMethod(this Type type, string methodName, params object[] args) + { + var argTypes = args == null || args.Length == 0 ? Type.EmptyTypes : Array.ConvertAll(args, o => o?.GetType() ?? typeof(object)); + var mi = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Static, null, argTypes, null); + if (mi == null) throw new ArgumentException(@"Method not found", nameof(methodName)); + return (T)mi.Invoke(null, args); + } + #if !(NETSTANDARD2_0) /// Invokes a method from a derived base class. /// The instance from the derived class for the method to invoke. @@ -222,7 +245,7 @@ namespace Vanara.Extensions returnType = methodInfo.ReturnType; var type = targetObject.GetType(); - var dynamicMethod = new DynamicMethod("", returnType, new [] { type, typeof(object) }, type); + var dynamicMethod = new DynamicMethod("", returnType, new[] { type, typeof(object) }, type); var iLGenerator = dynamicMethod.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); // this @@ -243,7 +266,7 @@ namespace Vanara.Extensions iLGenerator.Emit(OpCodes.Call, methodInfo); iLGenerator.Emit(OpCodes.Ret); - return dynamicMethod.Invoke(null, new [] { targetObject, arguments }); + return dynamicMethod.Invoke(null, new[] { targetObject, arguments }); } #endif