Question

    

Cette question a déjà une réponse ici:

         

J'ai le code suivant:

 public class ClassExample
{

    void DoSomthing<T>(string name, T value)
    {
        SendToDatabase(name, value);
    }

    public class ParameterType
    {
        public readonly string Name;
        public readonly Type DisplayType;
        public readonly string Value;

        public ParameterType(string name, Type type, string value)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
            if (type == null)
                throw new ArgumentNullException("type");

            this.Name = name;
            this.DisplayType = type;
            this.Value = value;
        }
    }

    public void GetTypes()
    {
        List<ParameterType> l = report.GetParameterTypes();

        foreach (ParameterType p in l)
        {
            DoSomthing<p.DisplayType>(p.Name, (p.DisplayType)p.Value);
        }

    }
}

Maintenant, je sais que je ne peux pas faire DoSomething () existe-t-il un autre moyen d'utiliser cette fonction?

Était-ce utile?

La solution

Vous pouvez le faire, mais cela implique une réflexion, mais vous pouvez le faire.

typeof(ClassExample)
    .GetMethod("DoSomething")
    .MakeGenericMethod(p.DisplayType)
    .Invoke(this, new object[] { p.Name, p.Value });

Ceci examinera le sommet de la classe contenante, obtiendra les informations sur la méthode, créera une méthode générique avec le type approprié, puis vous pourrez appeler Invoke dessus.

Autres conseils

this.GetType().GetMethod("DoSomething").MakeGenericMethod(p.Value.GetType()).Invoke(this, new object[]{p.Name, p.Value});

Devrait fonctionner.

Les types génériques ne peuvent pas être spécifiés au moment de l'exécution comme vous le souhaitez ici.

L’option la plus simple serait d’ajouter une surcharge non générique de DoSomething, ou d’appeler simplement DoSomething<object> et d’ignorer p.DisplayType. À moins que SendToDatabase ne dépende du type au moment de la compilation de value (et que ce ne soit probablement pas le cas), il ne devrait y avoir aucun problème à lui donner un object.

Si vous ne pouvez pas faire cela, vous devrez appeler <=> en utilisant la réflexion et vous obtiendrez un coup dur en termes de performances.

Nous devons d’abord convertir p.Value le bon type, car même si nous connaissons le type au moment de la compilation, nous ne pouvons pas passer la chaîne directement à la méthode ...

DoSomething<Int32>( "10" ); // Build error

Pour les types numériques simples et DateTime, nous pouvons utiliser

object convertedValue = Convert.ChangeType(p.Value, p.DisplayType);

Nous pouvons maintenant utiliser la réflexion pour appeler la méthode générique requise ...

typeof(ClassExample)
    .GetMethod("DoSomething")
    .MakeGenericMethod(p.DisplayType)
    .Invoke(this, new object[] { p.Name, convertedValue });

Dire strictement que vous pouvez utiliser MethodInfo.MakeGenericMethod pour cela.

Mais je recommande de remplacer DoSomething par une forme non générique, car il n’est pas évident qu’il soit réellement générique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top