2010-07-23 10 views
7

मैं एक MethodInfo एक समारोह में पारित किया है की एक सामान्य उदाहरण है और मैं निम्नलिखितमैं कैसे तय करते हैं कि एक विधि एक सामान्य विधि

MethodInfo containsMethod = typeof(ICollection<>).GetMethod("Contains"); 
if (methodInfo.Equals(containsMethod) 
{ 
    // do something 
} 

क्या करना चाहते हैं लेकिन यह क्योंकि MethodInfo काम नहीं करता है एक विशिष्ट सामान्य प्रकार है। उदाहरण के लिए काम करता है अगर मुझे पता था कि आईसीओलेक्शन हमेशा स्ट्रिंग प्रकार का था।

MethodInfo containsMethod = typeof(ICollection<string>).GetMethod("Contains"); 
if (methodInfo.Equals(containsMethod) 
{ 
    // do something 
} 

मैं कैसे जांच कर सकते हैं कि क्या MethodInfo एक किसी भी देखभाल किस प्रकार है बिना सामान्य विधि का उदाहरण आपके द्वारा लिखा गया है?

धन्यवाद।

संपादित करें: प्रश्न स्पष्टीकरण

के रूप में सही ढंग से बताया विधि सामान्य नहीं है, लेकिन युक्त वर्ग इतना है सवाल यह है कि अधिक मैं कैसे पता लगाने के लिए अगर MethodInfo एक प्रकार जो ICollection के द्वारा लिखे गए उदाहरण है के लिए है <>।

संपादित करें: अधिक संदर्भ

मैं एक Linq प्रदाता लिख ​​रहा हूँ और संभाल करने के लिए मामले "में"

IList<string> myList = new List<string>{ "1", "2" }; 

from Something s in ... 
where myList.Contains(s.name) 
select s; 

उत्तर

3

आप घोषित प्रकार की जांच कर सकता है:

if(methodInfo.Name == "Contains" 
    && methodInfo.DeclaringType.IsGenericType 
    && methodInfo.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection<>)) 
{ 
+0

सरल और स्पष्ट आईएमओ, धन्यवाद। –

4

ध्यान दें कि ICollection<T>.Containsनहीं एक सामान्य तरीका है की कोशिश कर रहा है - यह एक गैर है जेनेरिक एक सामान्य प्रकार की विधि। अन्यथा IsGenericMethod और GetGenericTypeDefinition मदद करेगा। आप सामान्य प्रकार की परिभाषा (DeclaringType.GetGenericTypeDefinition()) प्राप्त कर सकते हैं और Contains पर वापस काम कर सकते हैं, लेकिन मुझे आश्चर्य है कि क्या आप इस समस्या को कठिन तरीके से देख रहे हैं।

आमतौर पर, यदि आप प्रतिबिंब का उपयोग कर रहे हैं, यह व्यावहारिक गैर सामान्य IList को छोड़ने के लिए हो सकता है - जब तक आप जरूरत प्रकार के डेटा (उदाहरण के लिए, मेटा-प्रोग्रामिंग के लिए)। और उस स्थिति में, मैं यह देखने के लिए बारीकी से देख रहा हूं कि क्या आप यहां सेटअप को सरल बना सकते हैं।

+0

उत्तर के लिए धन्यवाद।जो कुछ मैं प्राप्त करने की कोशिश कर रहा हूं उसके लिए ऊपर कुछ संदर्भ जोड़ा गया है। DeclaringType दृष्टिकोण वादा करता है, मैं कोशिश करूँगा और वापस आऊंगा। –

0

समस्या यह है कि आपके पास सामान्य विधि नहीं है: आपके पास सामान्य प्रकार पर एक गैर-सामान्य विधि है। मुझे खुले जेनेरिक प्रकार पर एक विधि परिभाषा से सीधे बंद सामान्य जेनेरिक प्रकार या इसके विपरीत विधि पर जाने के लिए प्रतिबिंब का उपयोग करने के तरीके के बारे में पता नहीं है। हालांकि, अगर आप इस तथ्य है कि तरीकों खुला और बंद सामान्य प्रकार पर 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 
} 
2

कुछ त्रुटि जांच में इसे जोड़ने की आवश्यकता होगी, लेकिन मेरा मानना ​​है कि यह वही करता है जो आप चाहते हैं। आप पैरामीटर के रूप में किसी प्रकार के तर्क के साथ या बिना किसी विधि का उपयोग कर सकते हैं।

static bool IsContainsMethod(MethodInfo methodInfo) 
{ 
    Type[] types = { methodInfo.GetParameters().First().ParameterType }; 
    MethodInfo containsMethod = typeof(ICollection<>).MakeGenericType(types).GetMethod("Contains"); 
    return methodInfo.Equals(containsMethod); 
} 
0

इस विधि

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

} 
संबंधित मुद्दे