Как создать метод расширения для ToString? - PullRequest
48 голосов
/ 13 февраля 2011

Я пробовал это:

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);
    }
}

Но это не работает, как для string[], так и List<string>.Может быть, мне нужны особые аннотации?

Ответы [ 3 ]

107 голосов
/ 13 февраля 2011

Методы расширения проверяются, только если нет подходящих подходящих методов , которые соответствуют. В случае вызова ToString() будет всегда подходящим подходящим методом, а именно, ToString() на object. Целью методов расширения является расширение набора методов, доступных для типа, а не переопределение существующих методов; Вот почему они называются "методы расширения". Если вы хотите переопределить существующий метод, вам придется создать переопределяющий метод.

5 голосов
/ 13 февраля 2011

Звучит так, как будто вы хотите заменить то, что возвращает files.ToString(). Вы не сможете сделать это без написания пользовательского класса, назначающего files как (т.е. наследовать от List и переопределять ToString().)

Во-первых, избавьтесь от универсального типа (<T>), вы его не используете. Затем вам нужно будет переименовать метод расширения, потому что вызов files.ToString() просто вызовет метод ToString списка.

Это делает то, что вы ищете.

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());
    }
}
4 голосов
/ 13 февраля 2011

Просто вы Не следует использовать имя ToString для метода Extension, так как он никогда не будет вызван, потому что этот метод уже существует и вы не должны использовать T как бесполезно там.

Например, я попробовал это, и снова он вернул то же самое:

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

выход:

shekhar, shekhar, shekhar, shekhar

так что на этот раз я использовал int, и он все еще работал, потому что у Т нет другого применения, кроме изменения Прототипа Метода.

Так просто, почему вы используете ToString Литерал в качестве имени метода, так как оно уже существует, и вы не можете переопределить его в методе расширения , вот почему вам пришлось использовать это T чтобы сделать его общим. Используйте другое имя, например

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

Таким образом, вам не нужно будет использовать generic, поскольку он там бесполезен, и вы можете просто назвать его как всегда.

<Ч />

Тем не менее, ваш код работает на меня. вот что я попробовал ( в 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);
        }
    }

А на выходе было shekhar, shekhar, shekhar, shekhar

Поскольку вы указали T в ToString<T>, вам нужно будет упомянуть тип типа string или int при вызове метода ToString.

...