Files
xCommons/Helpers/XGenericHelper.cs

157 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using xCommons.Extensions;
namespace xCommons.Helpers
{
public static class XGenericHelper
{
/// <summary>
/// Invoke a Generic Method of Specified Type ...
/// </summary>
/// <param name="source"></param>
/// <param name="methodName"></param>
/// <param name="runtimeType"></param>
/// <param name="args"></param>
public static void InvokeGenericMethod(
this Type source,
string methodName,
Type runtimeType,
params object[] args
)
{
//
source.InvokeGenericMethod<object>(
args: args,
methodName: methodName,
runtimeType: runtimeType
);
}
/// <summary>
/// Invoke a Generic Method of Specified Type ...
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="source"></param>
/// <param name="methodName"></param>
/// <param name="runtimeType"></param>
/// <param name="args"></param>
/// <returns></returns>
public static TResponse InvokeGenericMethod<TResponse>(
this Type source,
string methodName,
Type runtimeType,
params object[] args
)
{
//
var overLoads = source.GetGenericMethodInfo(
methodName: methodName
);
if (!overLoads.HasChild())
{
return default;
}
//
var method = overLoads.ElementAt(0);
MethodInfo genericMethod = method.MakeGenericMethod(runtimeType);
//
var resultObj = genericMethod.Invoke(null, args);
var result = (TResponse)resultObj;
//
return result;
}
/// <summary>
/// Invoke a Generic Method of Specified Type ...
/// </summary>
/// <param name="source"></param>
/// <param name="methodName"></param>
/// <param name="runtimeTypes"></param>
/// <param name="args"></param>
public static void InvokeGenericMethod(
this Type source,
string methodName,
Type[] runtimeTypes,
params object[] args
)
{
//
source.InvokeGenericMethod<object>(
args: args,
methodName: methodName,
runtimeTypes: runtimeTypes
);
}
/// <summary>
/// Invoke a Generic Method of Specified Type ...
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="source"></param>
/// <param name="methodName"></param>
/// <param name="runtimeTypes"></param>
/// <param name="args"></param>
/// <returns></returns>
public static TResponse InvokeGenericMethod<TResponse>(
this Type source,
string methodName,
Type[] runtimeTypes,
params object[] args
)
{
//
var overLoads = source.GetGenericMethodInfo(
methodName: methodName
);
if (!overLoads.HasChild())
{
return default;
}
//
// Detect a Method by Generic Types ...
// var method = overLoads.ElementAt(0);
var method = overLoads.First(m => m.GetGenericArguments().Length == runtimeTypes.Length);
MethodInfo genericMethod = method.MakeGenericMethod(runtimeTypes);
//
var resultObj = genericMethod.Invoke(null, args);
var result = resultObj.ConvertTo<TResponse>();
//
return result;
}
/// <summary>
/// Extract a Generic Method's Overloads ...
/// </summary>
/// <param name="source"></param>
/// <param name="methodName"></param>
/// <returns></returns>
public static List<MethodInfo> GetGenericMethodInfo(
this Type source,
string methodName
)
{
//
var methods = source
.GetMethods();
//
var result = methods
.Where(mi =>
mi.Name == methodName &&
mi.IsGenericMethodDefinition)
.ToList();
//
return result;
}
}
}