Roep de "ToString" -methode aan door reflectie

Ik probeer de MethodInfo "ToString" als volgt op te halen:

MethodInfo method = MyType.GetMethod("ToString", 
                                     BindingFlags.Public | BindingFlags.Instance);

Er wordt een uitzondering gegenereerd "Meerdere overeenkomst gevonden".

0
Wat is MyType eigenlijk? Dat type heeft mogelijk overbelastingen voor ToString() , maar het heeft altijd de parameterloze.
toegevoegd de auteur BoltClock, de bron
Om welke reden kunt u niet gewoon ToString aanroepen? Zien als elk object er een heeft ...
toegevoegd de auteur Oded, de bron
@AdamHouldsworth - Mogelijk, hoewel OP niet vermeld, op één of andere manier.
toegevoegd de auteur Oded, de bron
@Oded zou kunnen proberen om één te krijgen met een andere handtekening?
toegevoegd de auteur Adam Houldsworth, de bron

8 antwoord

Uw type bevat meerdere ToString() overloads en GetMethod weet niet welke u wilt.

Gebruik de volgende syntaxis om aan te geven dat u de overbelasting wilt die geen parameters in beslag neemt:

MethodInfo method = myType.GetMethod("ToString", Type.EmptyTypes); 

Opmerking: Aangezien ToString() is gedefinieerd op System.Object , hoeft u geen reflectie te gebruiken om een ​​object met een onbekend type te gebruiken:

object myObject = ...;
string s = myObject.ToString();//works
6
toegevoegd

ToString() is a member of System.Object and thus it is one of the very few methods that you don't need reflection for when you wat to call it on an unknown Type.

De uitzondering ligt in de overbelastingen voor Tostring (dat wil zeggen int.ToString (tekenreeksen) , maar om een ​​van deze te bellen, moet u weten welke u zoekt.

En die overlays veroorzaken de fout die u ziet. Je zult specifiek moeten zijn.

3
toegevoegd

U moet aangeven dat u degene wilt zonder argumenten:

var method = MyType.GetMethod("ToString", 
                              new Type[0]);

BindingFlags.Public | BindingFlags.Instance is the default values, no need to specify them.

1
toegevoegd

Waarschijnlijk zijn er meer dan één ToString() methode. Bijvoorbeeld: double heeft vier varianten (de overschrijving van virtueel object. ToString() plus drie varianten)

Proberen

var variants = MyType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
               .Where(p => p.Name == "ToString");

it will return all the variants of ToString

or, if you know the parameters of "your" ToString

var toString = MyType.GetMethod("ToString", 
               BindingFlags.Public | BindingFlags.Instance, 
               null, arrayOfParametersType, null);
1
toegevoegd

Controleer dat als u ToString() wilt overschrijven, u echt het sleutelwoord negeren gebruikt:

class MyType
{
     public override string ToString()
     {
         return "Whatever";
     }
 }

Anders verberg je de object.ToString() -versie in plaats van echt te overschrijven.

0
toegevoegd

In een scenario als dit, wanneer u weet dat de methode bestaat (mogelijk met een aantal overbelastingen om de zaken te compliceren), kan het nuttig zijn om een ​​ Reflection helper library die het zware werk voor je doet.

Met Fasterflect kunt u bijvoorbeeld eenvoudig het volgende doen om een ​​methode op te roepen met behulp van de "best beschikbare overeenkomst", gegeven de opgegeven parameters (in het onderstaande voorbeeld vertegenwoordigt het optionele argument 42 enige waarde die u wilt gebruiken bij het aanroepen van de methode ):

var obj = ...
var result = obj.TryCallMethodWithValues( "ToString", 42 );

In mijn ervaring loont het vrij snel om een ​​goed geteste bibliotheek te gebruiken in plaats van handcodering (in dit geval reflectie).

Disclaimer: ik lever een bijdrage aan het Fasterflect-project.

0
toegevoegd

ToString can be overloaded. And on many types it is.

Eerst moet je controleren of de ToString die je wilt bellen, het overschreven -object is. ToString() of IFormattable.ToString (tekenreeksindeling, IFformatProvider-indelingProvider)) , omdat u eenvoudig kunt voorkomen dat er wordt gereflecteerd in deze gevallen.

U kunt een overbelasting van GetMethod gebruiken die de parameter Type [] types nodig heeft om te kiezen welke overbelasting van ToString u wilt.

U kunt bijvoorbeeld GetMethod ("ToString", nieuw type [] {gebruiken }) om de parameterloze ToString() te verkrijgen.

0
toegevoegd
MethodInfo method = typeof(MyType).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance);

Dat werkt echt voor mij ...

U hebt waarschijnlijk een overbelasting (overload) op ToString. Aangezien u meerdere ToString-methoden (overloads) kunt gebruiken die openbaar zijn, kan deze regel meerdere ToString-methoden retourneren.

Je zou iets als:
moeten gebruiken     GetMethod (string naam, Type [] types)

Waar Type [] een array van de typen bevat, heeft de methode die u zoekt (in uw geval geen)

(Met dank aan reacties, heb hier ook iets van geleerd :)

0
toegevoegd
Werkt alleen als er geen overbelasting is ...
toegevoegd de auteur jgauffin, de bron
Op zichzelf is de code prima. Het mislukt als meer dan één methode genaamd "ToString" wordt gevonden binnen zijn zoekparameters: Public | Aanleg.
toegevoegd de auteur Adam Houldsworth, de bron