Как определить, является ли метод универсальным экземпляром универсального метода

Фильтр вернет любые элементы, которые частично совпадают. Работа, предложенная 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

7
задан Mike Q 23 July 2010 в 13:26
поделиться

5 ответов

​​

Вы можете проверить тип объявления:

if( methodInfo.Name == "Contains" 
    &&  methodInfo.DeclaringType.IsGenericType
    && methodInfo.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection<>))
{
3
ответ дан 7 December 2019 в 03:09
поделиться

Обратите внимание, что ICollection .Contains является не универсальным методом - это неуниверсальный метод универсальный тип. В противном случае помогли бы IsGenericMethod и GetGenericTypeDefinition . Вы можете получить определение универсального типа ( DeclaringType.GetGenericTypeDefinition () ) и вернуться к Contains , но мне интересно, подходите ли вы к этой проблеме жестко.

Обычно, если вы используете отражение, может быть прагматично перейти к неуниверсальному IList - если вам не нужны данные типа (например, для метапрограммирования) . И в этом случае я бы подумал о том, чтобы присмотреться, чтобы увидеть, можете ли вы упростить настройку здесь.

4
ответ дан 7 December 2019 в 03:09
поделиться

попробуйте этот метод

    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;
        }
    }

}
0
ответ дан 7 December 2019 в 03:09
поделиться

К этому нужно добавить некоторую проверку ошибок, но я считаю, что это примерно делает то, что вы хотите. Вы можете использовать метод с аргументом типа или без него в качестве параметра.

static bool IsContainsMethod(MethodInfo methodInfo)
{
    Type[] types = { methodInfo.GetParameters().First().ParameterType };
    MethodInfo containsMethod = typeof(ICollection<>).MakeGenericType(types).GetMethod("Contains");
    return methodInfo.Equals(containsMethod);
}
2
ответ дан 7 December 2019 в 03:09
поделиться

Проблема в том, что у вас нет универсального метода: у вас есть неуниверсальный метод для универсального типа. Я не знаю, как использовать отражение, чтобы перейти непосредственно от определения метода в открытом универсальном типе к тому же методу в закрытом универсальном типе или наоборот. Однако вы можете воспользоваться тем фактом, что методы, возвращаемые функцией 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
}
0
ответ дан 7 December 2019 в 03:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: