Фильтр вернет любые элементы, которые частично совпадают. Работа, предложенная Microsoft, заключается в том, чтобы затем искать фильтрованный массив для точных совпадений.
Function FilterExactMatch(astrItems() As String, _
strSearch As String) As String()
' This function searches a string array for elements
' that exactly match the search string.
Dim astrFilter() As String
Dim astrTemp() As String
Dim lngUpper As Long
Dim lngLower As Long
Dim lngIndex As Long
Dim lngCount As Long
' Filter array for search string.
astrFilter = Filter(astrItems, strSearch)
' Store upper and lower bounds of resulting array.
lngUpper = UBound(astrFilter)
lngLower = LBound(astrFilter)
' Resize temporary array to be same size.
ReDim astrTemp(lngLower To lngUpper)
' Loop through each element in filtered array.
For lngIndex = lngLower To lngUpper
' Check that element matches search string exactly.
If astrFilter(lngIndex) = strSearch Then
' Store elements that match exactly in another array.
astrTemp(lngCount) = strSearch
lngCount = lngCount + 1
End If
Next lngIndex
' Resize array containing exact matches.
ReDim Preserve astrTemp(lngLower To lngCount - 1)
' Return array containing exact matches.
FilterExactMatch = astrTemp
End Function
Этот код взят из http://msdn.microsoft.com/en-us/library /office/aa164525%28v=office.10%29.aspx
Вы можете проверить тип объявления:
if( methodInfo.Name == "Contains"
&& methodInfo.DeclaringType.IsGenericType
&& methodInfo.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection<>))
{
Обратите внимание, что ICollection
является не универсальным методом - это неуниверсальный метод универсальный тип. В противном случае помогли бы IsGenericMethod
и GetGenericTypeDefinition
. Вы можете получить определение универсального типа ( DeclaringType.GetGenericTypeDefinition ()
) и вернуться к Contains
, но мне интересно, подходите ли вы к этой проблеме жестко.
Обычно, если вы используете отражение, может быть прагматично перейти к неуниверсальному IList
- если вам не нужны данные типа (например, для метапрограммирования) . И в этом случае я бы подумал о том, чтобы присмотреться, чтобы увидеть, можете ли вы упростить настройку здесь.
попробуйте этот метод
public static bool CheckGenericMethod(MethodInfo methodInfo)
{
bool areSimilarMethods = false;
MethodInfo methodToCompare = typeof(ISomeInterface<>).GetMethod("func");
Type interfaceInfo = methodInfo.DeclaringType.GetInterface(methodToCompare.DeclaringType.FullName);
if (interfaceInfo != null)
areSimilarMethods = (methodToCompare.Name.Equals(methodInfo.Name)
&& interfaceInfo.FullName.Contains(methodToCompare.DeclaringType.FullName));
else
{
areSimilarMethods = methodToCompare.DeclaringType.Equals(methodInfo.DeclaringType);
}
return areSimilarMethods;
}
и вот полный пример использования.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace TestReflection
{
public class Program
{
static void Main(string[] args)
{
MethodInfo info1 = typeof(ISomeInterface<>).GetMethod("func");
MethodInfo info2 = typeof(MyStringCollection).GetMethod("func");
MethodInfo info3 = typeof(MyProgramCollection).GetMethod("func");
MethodInfo info4 = typeof(MyXCollection).GetMethod("func");
if (CheckGenericMethod(info1)) Console.WriteLine("true");else Console.WriteLine("false");
if (CheckGenericMethod(info2)) Console.WriteLine("true");else Console.WriteLine("false");
if (CheckGenericMethod(info3)) Console.WriteLine("true");else Console.WriteLine("false");
if (CheckGenericMethod(info4)) Console.WriteLine("true"); else Console.WriteLine("false");
Console.ReadKey();
}
public static bool CheckGenericMethod(MethodInfo methodInfo)
{
bool areSimilarMethods = false;
MethodInfo methodToCompare = typeof(ISomeInterface<>).GetMethod("func");
Type interfaceInfo = methodInfo.DeclaringType.GetInterface(methodToCompare.DeclaringType.FullName);
if (interfaceInfo != null)
areSimilarMethods = (methodToCompare.Name.Equals(methodInfo.Name)
&& interfaceInfo.FullName.Contains(methodToCompare.DeclaringType.FullName));
else
{
areSimilarMethods = methodToCompare.DeclaringType.Equals(methodInfo.DeclaringType);
}
return areSimilarMethods;
}
}
public interface ISomeInterface<T> where T : class
{
T func(T s);
}
public class MyStringCollection : ISomeInterface<string>
{
public string func(string s)
{
return s;
}
}
public class MyProgramCollection : ISomeInterface<Program>
{
public Program func(Program s)
{
return s;
}
}
public class MyXCollection
{
public int func(int s)
{
return s;
}
}
}
К этому нужно добавить некоторую проверку ошибок, но я считаю, что это примерно делает то, что вы хотите. Вы можете использовать метод с аргументом типа или без него в качестве параметра.
static bool IsContainsMethod(MethodInfo methodInfo)
{
Type[] types = { methodInfo.GetParameters().First().ParameterType };
MethodInfo containsMethod = typeof(ICollection<>).MakeGenericType(types).GetMethod("Contains");
return methodInfo.Equals(containsMethod);
}
Проблема в том, что у вас нет универсального метода: у вас есть неуниверсальный метод для универсального типа. Я не знаю, как использовать отражение, чтобы перейти непосредственно от определения метода в открытом универсальном типе к тому же методу в закрытом универсальном типе или наоборот. Однако вы можете воспользоваться тем фактом, что методы, возвращаемые функцией GetMethods ()
для открытых и закрытых универсальных типов, всегда должны быть в одном порядке и выполнять перевод по индексу:
MethodInfo containsMethod = typeof(ICollection<>).GetMethod("Contains");
var methodIndex = Array.IndexOf(methodInfo.DeclaringType.GetMethods(), methodInfo);
var methodOnTypeDefinition = methodInfo.DeclaringType.GetGenericTypeDefinition().GetMethods()[methodIndex];
if (methodOnTypeDefinition.Equals(containsMethod))
{
// do something
}