Flurl/Flurl.Test/ReflectionHelper.cs
2014-03-27 15:55:56 -05:00

104 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Flurl.Test
{
public static class ReflectionHelper
{
public static MethodInfo[] GetAllExtensionMethods(Assembly asm) {
// http://stackoverflow.com/a/299526/62600
return (
from type in asm.GetTypes()
where type.IsSealed && !type.IsGenericType && !type.IsNested
from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
select method).ToArray();
}
public static bool IsEquivalentExtensionMethod(MethodInfo method1, MethodInfo method2, Type method2ExtType) {
if (method1.Name != method2.Name)
return false;
if (!AreSameType(method1.ReturnType, method2.ReturnType))
return false;
var genArgs1 = method1.GetGenericArguments();
var genArgs2 = method2.GetGenericArguments();
if (genArgs1.Length != genArgs2.Length)
return false;
for (int i = 0; i < genArgs1.Length; i++) {
if (!AreSameType(genArgs1[i], genArgs2[i]))
return false;
}
var args1 = method1.GetParameters();
var args2 = method2.GetParameters();
if (args1.Length != args2.Length)
return false;
if (!AreSameType(args2[0].ParameterType, method2ExtType))
return false;
for (int i = 1; i < args1.Length; i++) {
if (args1[i].Name != args2[i].Name) return false;
if (!AreSameType(args1[i].ParameterType, args2[i].ParameterType)) return false;
if (args1[i].IsOptional != args2[i].IsOptional) return false;
if (!AreSameValue(args1[i].DefaultValue, args2[i].DefaultValue)) return false;
if (args1[i].IsIn != args2[i].IsIn) return false;
}
return true;
}
public static bool AreSameValue(object a, object b) {
if (a == null && b == null)
return true;
if (a == null ^ b == null)
return false;
// ok, neither is null
return a.Equals(b);
}
public static bool AreSameType(Type a, Type b) {
if (a.IsGenericParameter && b.IsGenericParameter) {
var constraintsA = a.GetGenericParameterConstraints();
var constraintsB = b.GetGenericParameterConstraints();
if (constraintsA.Length != constraintsB.Length)
return false;
for (int i = 0; i < constraintsA.Length; i++) {
if (!AreSameType(constraintsA[i], constraintsB[i]))
return false;
}
return true;
}
if (a.IsGenericType && b.IsGenericType) {
if (a.GetGenericTypeDefinition() != b.GetGenericTypeDefinition())
return false;
var genArgsA = a.GetGenericArguments();
var genArgsB = b.GetGenericArguments();
if (genArgsA.Length != genArgsB.Length)
return false;
for (int i = 0; i < genArgsA.Length; i++) {
if (!AreSameType(genArgsA[i], genArgsB[i]))
return false;
}
return true;
}
return a == b;
}
}
}