web-dev-qa-db-fra.com

Méthode d'extension C # pour objet

Est-ce une bonne idée d'utiliser une méthode d'extension sur la classe Object?

Je me demandais si, en enregistrant cette méthode, vous encouriez une pénalité de performance, car elle serait chargée sur chaque objet chargé dans le contexte.

28
Mandrake

En plus d'une autre réponse:

il n'y aurait aucune pénalité de performance car les méthodes d'extension sont une fonctionnalité du compilateur. Considérons le code suivant:

public static class MyExtensions
{
    public static void MyMethod(this object) { ... }
} 

object obj = new object();
obj.MyMethod();

L'appel à MyMethod sera en fait compilé pour:

MyExtensions.MyMethod(obj);
29
Andrew Bezzub

Les performances ne seront pas pénalisées, car elles ne s’attacheront pas à tous les types du système, mais elles pourront simplement être appelées sur n’importe quel type du système. Tout ce qui va arriver, c'est que la méthode va apparaître sur every single object in intellisense.

La question est: avez-vous vraiment besoin-il d'être sur l'objet, ou peut-il être plus spécifique S'il doit être placé sur un objet, créez-le pour l'objet.

12
Darren Kopp

Si vous avez vraiment l'intention d'étendre chaque objet, le faire est la bonne chose à faire. Toutefois, si votre extension ne s'applique réellement qu'à un sous-ensemble d'objets, vous devez l'appliquer au niveau hiérarchique le plus élevé nécessaire, mais pas davantage.

En outre, la méthode ne sera disponible que si votre espace de nom est importé.

J'ai étendu Object pour une méthode qui tente de transtyper vers un type spécifié:

public static T TryCast<T>(this object input)
{
    bool success;
    return TryCast<T>(input, out success);
}

Je l'ai aussi surchargé pour prendre dans un success bool (comme le fait TryParse):

public static T TryCast<T>(this object input, out bool success)
{
    success = true;
    if(input is T)
        return (T)input;
    success = false;
    return default(T);
}

Depuis, j'ai développé cela pour tenter également d'analyser input (en utilisant ToString et en utilisant un convertisseur), mais cela devient plus compliqué.

3
Mark Avenius

Est-ce une bonne idée d'utiliser une méthode d'extension sur la classe Object?

Oui, il y a des cas où c'est une excellente idée. Il n'y a aucune pénalité de performance en utilisant une méthode d'extension sur la classe Object. Tant que vous n'appelez pas cette méthode, les performances de votre application ne seront pas du tout affectées.

Par exemple, considérons la méthode d'extension suivante qui répertorie toutes les propriétés d'un objet donné et le convertit en dictionnaire:

public static IDictionary<string, object> ObjectToDictionary(object instance)
{
    var dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
    if (instance != null)
    {
        foreach (var descriptor in TypeDescriptor.GetProperties(instance))
        {
            object value = descriptor.GetValue(instance);
            dictionary.Add(descriptor.Name, value);
        }
    }
    return dictionary;
}
2
Darin Dimitrov

C'est une vieille question, mais je ne vois aucune réponse ici qui tente de réutiliser la fonction de recherche existante pour les objets actifs. Voici une méthode d'extension succincte avec une surcharge optionnelle pour la recherche d'objets inactifs.

using System.Linq;

namespace UnityEngine {

public static class GameObjectExtensionMethods {

    public static GameObject Find(this GameObject gameObject, string name, 
        bool inactive = false) {

       if (inactive)
          return Resources.FindObjectsOfTypeAll<GameObject>().Where(
             a => a.name == name).FirstOrDefault();
       else
           return GameObject.Find(name);
    }
  }
}

Si vous utilisez cette fonction dans la méthode Update, vous pouvez envisager de modifier l'instruction LINQ avec un tableau pour le parcours en boucle afin d'éliminer la génération de déchets.

0
Shaun

L'exemple suivant illustre la méthode d'extension utilisée.

namespace NamespaceName
{
public static class CommonUtil
{
    public static string ListToString(this IList list)
    {
        StringBuilder result = new StringBuilder("");

        if (list.Count > 0)
        {
            result.Append(list[0].ToString());
            for (int i = 1; i < list.Count; i++)
                result.AppendFormat(", {0}", list[i].ToString());
        }
        return result.ToString();
    }
  }
}

L'exemple suivant montre comment cette méthode peut être utilisée.

var _list = DataContextORM.ExecuteQuery<string>("Select name from products").ToList();
string result = _list.ListToString();
0
plywoods