2016-11-12 3 views
-2

Wie erhalten alle Methoden für "String" Typ, mit allen Erweiterungen wie "Aggregate", "Select" und andere durch C# Reflexion? Ich weiß, dass Typ meisten implementieren Schnittstelle IEnumerable <>, aber alle diese Erweiterungsmethoden in Enumerable-Klasse mit ersten Gattungs parametr TSource.Ok ... Code:Alle Erweiterungen Methoden für den Typ String

var type = typeof(string).GetMethods(); //i get all methods string type 
//I want get for this type all extensions methods like "Select" "Where" 
//so i get all interfaces 
type.GetInterfaces(); 
//ICompareble 
//ICloneable 
//... 
//IEnumearable, but all this interfaces don't have extensions methods 
//They locate in Enumerable class 
//how i can use string type go to Enumerable class and get all this methods 
//Somthigs like this 
typeof(Enumerable).GetMethods(); //i want get all this methods but using type "string" 
//Aggregate 
//Select 
//where 
+1

Ich denke, es ist einfach für Sie, einen reproduzierbaren Code für Ihr Problem zu veröffentlichen, so dass wir es an unseren Maschinen testen können. –

+0

this [link] http://stackoverflow.com/questions/299515/reflection- to-identify-extension-methods Methode funktioniert nicht, weil er ersten Parameter typeof (string) verwendet, in meiner Version haben diese Methoden erste parametr generische TSource. – itihonov

Antwort

1

Erweiterungsmethoden können selbstverständlich in verschiedenen Baugruppen definiert werden, so Die erste Frage ist, welche Baugruppen uns wichtig sind. Wir werden mit

var assemblies = GetType().Assembly 
    .GetReferencedAssemblies() 
    .Select(an => Assembly.Load(an)) 
    .Concat(Enumerable.Repeat(GetType().Assembly, 1)); 

zu (im Rahmen einer Instanz Methode oder Eigenschaft) beginnen erhalten die aktuellen Assembly und alle, die es verweist, wie die durchführbare Quelle für Erweiterungsmethoden verfügbar ist und dann. Andere Verwendungen haben andere Startpunkte.

Jetzt müssen wir alle Erweiterungsmethoden erhalten:

var availableExtensionMethods = assemblies 
    // First get all the types 
    .SelectMany(asse => asse.GetExportedTypes()) 
    // Cut out some which cannot be static classes first 
    .Where(t => t.IsAbstract && t.IsSealed && t.GetConstructors().Length == 0) 
    // Get all their methods. 
    .SelectMany(t => t.GetMethods()) 
    // Restrict to just the extension methods 
    .Where(m => m.GetCustomAttributes().Any(ca => ca is System.Runtime.CompilerServices.ExtensionAttribute) 
    // An extension method must have at least one parameter, but we'll rule out being 
    // messed up by some strangely defined method through weird direct use of 
    // the ExtensionAttribute attribute 
    && m.GetParameters().Length != 0) 
    // Get an object with the method and the first parameter we'll use below. 
    .Select(m => new {Method = m, FirstParam = m.GetParameters()[0]}); 

nun diejenigen, die direkt in Bezug auf string (SomeMethod(this string arg)) auf einer Basisklasse (SomeMethod(this object arg)) wird sein:

var stringExtensions = availableExtensionMethods 
    .Where(info => info.FirstParam.ParameterType.IsAssignableFrom(typeof(string))) 
    .Select(info => info.Method); 

Das obige würde (this IEnumerable<char> arg) einschließen. Um allgemein auf einen generischen Typ String implementiert definiert zu erhalten (zB (this IEnumerable<T> arg) würden wir verwenden:

var stringGenericInterfaces = typeof(string).GetInterfaces() 
    .Where(i => i.IsGenericType) 
    .Select(i => i.GetGenericTypeDefinition()); 
    var extensionsOnGenericInterfaces = from info in 
     availableExtensionMethods.Where(aem => aem.FirstParam.ParameterType.ContainsGenericParameters) 
     from inter in stringGenericInterfaces 
     where info.FirstParam.ParameterType.GetGenericTypeDefinition().IsAssignableFrom(inter) 
     select info.Method; 

können Sie Union diese dann zusammen zu bekommen, das Los

Ich habe nicht überprüft auf Einschränkungen hier allerdings enthalten..

+0

Vielen Dank, es ist Arbeit. Ich kann deine Antwort nicht bewerten, weil ich einen schlechten Ruf habe. Es ist meine erste Frage und ich habe "-2", habe keine Ahnung warum, vielleicht liegt es daran, dass ich ein schlechtes Englisch habe :)) – itihonov

0

Erweiterungsmethoden der Zeichenfolge werden in Enumerable Klasse und IEnumerable-Schnittstelle befindet, die in System.Linq Namespace in mscorlib Montage sind Sie können die Namen der Erweiterungsmethoden in System.Linq in einer Art und Weise wie diese:.

Verwandte Themen