137 lines
4.3 KiB
C#
137 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace NLua.Extensions
|
|
{
|
|
static class TypeExtensions
|
|
{
|
|
public static bool HasMethod(this Type t, string name)
|
|
{
|
|
var op = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
|
|
return op.Any(m => m.Name == name);
|
|
}
|
|
|
|
public static bool HasAdditionOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
|
|
return t.HasMethod("op_Addition");
|
|
}
|
|
|
|
public static bool HasSubtractionOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
|
|
return t.HasMethod("op_Subtraction");
|
|
}
|
|
|
|
public static bool HasMultiplyOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
|
|
return t.HasMethod("op_Multiply");
|
|
}
|
|
|
|
public static bool HasDivisionOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
|
|
return t.HasMethod("op_Division");
|
|
}
|
|
|
|
public static bool HasModulusOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
|
|
return t.HasMethod("op_Modulus");
|
|
}
|
|
|
|
public static bool HasUnaryNegationOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
// Unary - will always have only one version.
|
|
var op = t.GetMethod("op_UnaryNegation", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
|
|
return op != null;
|
|
}
|
|
|
|
public static bool HasEqualityOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
return t.HasMethod("op_Equality");
|
|
}
|
|
|
|
public static bool HasLessThanOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
|
|
return t.HasMethod("op_LessThan");
|
|
}
|
|
|
|
public static bool HasLessThanOrEqualOperator(this Type t)
|
|
{
|
|
if (t.IsPrimitive)
|
|
return true;
|
|
return t.HasMethod("op_LessThanOrEqual");
|
|
}
|
|
|
|
public static MethodInfo[] GetMethods(this Type t, string name, BindingFlags flags)
|
|
{
|
|
return t.GetMethods(flags).Where(m => m.Name == name).ToArray();
|
|
}
|
|
|
|
public static MethodInfo[] GetExtensionMethods(this Type type, string name, IEnumerable<Assembly> assemblies = null)
|
|
{
|
|
var types = new List<Type>();
|
|
|
|
types.AddRange(type.Assembly.GetTypes().Where(t => t.IsPublic));
|
|
|
|
if (assemblies != null)
|
|
{
|
|
foreach (Assembly item in assemblies)
|
|
{
|
|
if (item == type.Assembly)
|
|
continue;
|
|
types.AddRange(item.GetTypes().Where(t => t.IsPublic && t.IsClass && t.IsSealed && t.IsAbstract && !t.IsNested));
|
|
}
|
|
}
|
|
|
|
var query = types
|
|
.SelectMany(extensionType => extensionType.GetMethods(name, BindingFlags.Static | BindingFlags.Public),
|
|
(extensionType, method) => new {extensionType, method})
|
|
.Where(t => t.method.IsDefined(typeof(ExtensionAttribute), false))
|
|
.Where(t =>
|
|
t.method.GetParameters()[0].ParameterType == type ||
|
|
t.method.GetParameters()[0].ParameterType.IsAssignableFrom(type) ||
|
|
type.GetInterfaces().Contains(t.method.GetParameters()[0].ParameterType))
|
|
.Select(t => t.method);
|
|
|
|
return query.ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extends the System.Type-type to search for a given extended MethodeName.
|
|
/// </summary>
|
|
/// <param name="t"></param>
|
|
/// <param name="name"></param>
|
|
/// <param name="assemblies"></param>
|
|
/// <returns></returns>
|
|
public static MethodInfo GetExtensionMethod(this Type t, string name, IEnumerable<Assembly> assemblies = null)
|
|
{
|
|
var mi = t.GetExtensionMethods(name, assemblies).ToArray();
|
|
if (mi.Length == 0)
|
|
return null;
|
|
return mi[0];
|
|
}
|
|
}
|
|
} |