Как я могу переопределить метод ToString () для всех IEnumerable? - PullRequest
4 голосов
/ 14 марта 2012

Я хочу переопределить ToString() на IEnumerable<Int32>.

Я думал использовать методы расширения.

Но когда я делаю это ниже, он все равно вызывает ToString() наSystem.Object.Когда я переименовываю свой метод, он вызывает мой метод.

Поскольку мой метод расширения находится в статическом классе, я не могу переопределить.

Как мне добиться этого, чтобы мой ToString() реализация вызывается, когда я звоню .ToString() на List<Int32> например?

public static class ExtensionMethods
{
    public static new string ToString(this IEnumerable<Int32> set)
    {
        var sb = new StringBuilder();

        // Do some modifications on sb

        return sb.ToString();
    }
}

Ответы [ 4 ]

9 голосов
/ 14 марта 2012

Как я могу добиться этого, чтобы моя реализация ToString () вызывалась, когда я вызываю .ToString () для List, например?

Вы не можете, в принципе.Методы расширения только используются, если не найден соответствующий метод экземпляра.

Я предлагаю вам дать другому методу имя, избегая проблемы - и потенциальная путаница, которую ваш метод может вызватьпричина .

Обратите внимание, что даже если бы методы расширения были сопоставлены в предпочтении (скажем) методам, объявленным в object, это только изменит ваш компилируемый кодс соответствующей директивой using, а не с любым другим кодом, который уже связал вызов с обычным.

Если вы можете дать больше информации о том, чего вы пытаетесь достичь, мы можем помочьВы больше - но на данный момент что-то вроде ToDelimitedString (или что-то еще делает ваш метод) звучит как лучший выбор для меня.

3 голосов
/ 14 марта 2012

Нельзя заменить метод, использующий методы расширения.

При разрешении метода будет проверен метод, принадлежащий к типу, до , пытающийся найти подходящие методы расширения.

Другими словами, вы не можете заменить ToString, но да, вы можете создать свой собственный метод.

Либо создайте свой собственный тип IEnumerable<T> с переопределенным методом ToString, либоиспользуйте другое имя метода.Конечно, использование вашего собственного типа, конечно, будет работать только тогда, когда вы на самом деле используете этого типа.

0 голосов
/ 07 июля 2019

Вы не можете переопределить ToString, но вы можете создать универсальный метод.

Это простое решение, основанное на ответе Михаила Фрейдгейма (его ссылка не работает):

static public class Extensions {

    // extension for arrays, lists, any Enumerable -> AsString
    public static string AsString<T>(this IEnumerable<T> enumerable) {
        var sb = new StringBuilder();
        int inx = 0;
        foreach (var item in enumerable) {
            sb.Append($"{inx}: {item}\r\n");
            inx++;
        }
        return sb.ToString();
    }
}

Использование:

Console.WriteLine(arr.AsString());
Console.WriteLine(list.AsString());
Console.WriteLine(linqResult.AsString());
0 голосов
/ 05 мая 2013

Невозможно переопределить ToString, но вы можете создать оболочку , которую вы можете вызывать в любом месте, где вы используете IEnumerable<Int32>

Для вывода коллекции в виде строки я использую метод расширения

1008 *

public static string ToString<T>( this IEnumerable<T> messages)
{ 
     return ToString<T>(messages, Environment.NewLine, "" );
}



ToString<T>( this IEnumerable<T>messages, string separator, string sComment)

описано в моем посте Функция ToString для общего списка

См. Также похожие Переопределение ToString () списка

Подобная функция реализована как метод расширения, описанный в посте: ToString с разделителями-разделителями для массива, списка, словаря, универсального IEnumerable

...