web-dev-qa-db-fra.com

Comment créer une méthode d'extension pour ToString?

J'ai essayé ceci:

public static class ListHelper
{
    public static string ToString<T>(this IList<String> list)
    {
        return string.Join(", ", list.ToArray());
    }

    public static string ToString<T>(this String[] array)
    {
        return string.Join(", ", array);
    }
}

Mais cela ne fonctionne pas, tant pour string[] et List<string>. Peut-être que j'ai besoin d'annotations spéciales?

50
IAdapter

Les méthodes d'extension ne sont vérifiées que s'il y a pas de méthodes candidates applicables qui correspondent. Dans le cas d'un appel à ToString() il y aura toujours une méthode candidate applicable, à savoir, ToString() sur object. Le but des méthodes d'extension est de étendre l'ensemble des méthodes disponibles sur un type, et non de remplacer les méthodes existantes; c'est pourquoi ils sont appelés "méthodes d'extension". Si vous souhaitez remplacer une méthode existante, vous devrez créer une méthode prioritaire.

108
Eric Lippert

Il semble que vous souhaitiez remplacer ce que files.ToString() renvoie. Vous ne pourrez pas le faire sans écrire une classe personnalisée pour affecter files en tant que (c'est-à-dire hériter de List et remplacer ToString().)

Tout d'abord, débarrassez-vous du type générique (<T>), Vous ne l'utilisez pas. Ensuite, vous devrez renommer la méthode d'extension, car l'appel de files.ToString() appellera simplement la méthode ToString de la liste.

Cela fait ce que vous cherchez.

static class Program
{
    static void Main()
    {
        var list = new List<string> { {"a"}, {"b"}, {"c"} };
        string str = list.ToStringExtended();
    }
}


public static class ListHelper
{
    public static string ToStringExtended(this IList<String> list)
    {
        return string.Join(", ", list.ToArray());
    }
}
5
matt.dolfin

Simplement vous ne devriez pas utiliser le nom ToString pour la méthode d'extension car elle ne sera jamais appelée car cette méthode existe déjà et vous ne devriez pas N'utilisez pas T comme son inutile là-bas.

Par exemple, j'ai essayé cela et encore une fois, il a renvoyé la même chose:

Console.WriteLine(lst.ToString<int>());

production:

shekhar, shekhar, shekhar, shekhar

donc cette fois j'ai utilisé int et il a toujours fonctionné parce que T n'a pas d'autre utilité que de changer le prototype de méthode.

Alors simplement pourquoi utilisez-vous ToString Literal comme nom de méthode, car il existe déjà et vous ne pouvez pas le remplacer dans une méthode d'extension, c'est la raison pour laquelle vous avez dû utiliser ce T pour le rendre générique. Utilisez un nom différent comme

public static string ToMyString(this IList<String> list)

De cette façon, vous n'auriez pas à utiliser générique car il est inutile là-bas et vous pourriez simplement l'appeler comme toujours.


Cela dit, votre code fonctionne pour moi. voici ce que j'ai essayé (dans LINQPAD):

void Main()
{

    List<string> lst = new List<string>();
    lst.Add("shekhar");
    lst.Add("shekhar");
    lst.Add("shekhar");
    lst.Add("shekhar");
    lst.ToString<string>().Dump();
}

    public static class ListHelper
    {
        public static string ToString<T>(this IList<String> list)
        {
            return string.Join(", ", list.ToArray());
        }

        public static string ToString<T>(this String[] array)
        {
            return string.Join(", ", array);
        }
    }

Et la sortie était shekhar, shekhar, shekhar, shekhar

Puisque vous avez spécifié que T dans ToString<T> vous devrez mentionner un type comme string ou int lors de l'appel de la méthode ToString.

4
Shekhar_Pro