Подтвердить что ты не робот

Как создать общий метод расширения?

Я хочу разработать универсальный метод расширения, который должен упорядочить строку в алфавитном порядке, а затем по длине в порядке возрастания.

Я имею в виду

string[] names = { "Jon", "Marc", "Joel",
                  "Thomas", "Copsey","Konrad","Andrew","Brian","Bill"};

var query = names.OrderBy(a => a.Length).ThenBy(a => a);

Каков способ разработки универсального метода расширения?

Я пробовал:

public static class ExtensionOperation
    {
        public static T[] AlphaLengthWise<T>(this T[] names)
        {
            var query = names.OrderBy(a => a.Length).ThenBy(a => a);
            return query;
        }
    }

Я получил:

Ошибка 1: T не содержит определения длины

Ошибка 2: невозможно преобразовать System.Linq.IOrderedEnumerable в T[].

4b9b3361

Ответ 1

Первая ошибка заключается в том, что Length является свойством класса String, а в вашей общей версии тип параметра T неизвестен. Это может быть любой тип.

Вторая ошибка заключается в том, что вы возвращаете объект запроса, а не фактический результат. Возможно, вам придется вызвать ToArray() перед возвратом.

С небольшими изменениями вы можете придумать следующее:

public static class ExtensionOperation
{
    public static IEnumerable<T> AlphaLengthWise<T, L>(
        this IEnumerable<T> names, Func<T, L> lengthProvider)
    {
        return names
            .OrderBy(a => lengthProvider(a))
            .ThenBy(a => a);
    }
}

Что вы можете использовать следующим образом:

string[] names = { "Jon", "Marc", "Joel", "Thomas", "Copsey", "Konrad", "Andrew", "Brian", "Bill" };
var result = names. AlphaLengthWise(a => a.Length);

Ответ 2

Почему вы хотите сделать это в общем? Просто используйте

public static class ExtensionOperations
{
    public static IEnumerable<string> AlphaLengthWise(this string[] names)
    {
        var query = names.OrderBy(a => a.Length).ThenBy(a => a);
        return query;
    }
}

Ответ 3

Я думаю, вы можете немного смутить цель дженериков.

Generics - это способ адаптировать класс или метод к определенному типу. Общий метод или класс предназначены для работы для любого типа. Это наиболее легко проиллюстрировано в классе List<T>, где его можно настроить как список любого типа. Это дает вам тип безопасности, зная, что список содержит только этот тип.

Ваша задача предназначена для работы с определенным типом типа string. Дженерики не собираются решать проблему, которая связана с определенным типом.

Что вы хотите - это простой (не общий) метод расширения:

public static class ExtensionOperations
{
    public static IEnumerable<string> AlphaLengthWise(
        this IEnumerable<string> names)
    {
        if(names == null)
            throw new ArgumentNullException("names");

        return names.OrderBy(a => a.Length).ThenBy(a => a);
    }
}

Создание аргумента и возвращаемого типа IEnumerable<string> делает этот метод универсальным расширением, который может применяться к любому типу, реализующему IEnumerable<string>. Это будет включать string[], List<string>, ICollection<string>, IQueryable<string> и многие другие.

Ответ 4

Почему вы хотите, чтобы он был общим?

Это будет работать только тогда, когда T имеет свойство Length, и для этого вам понадобится интерфейс.

Кроме того, T должен быть IComparable.

Ответ 5

Я хочу разработать универсальный метод расширения, который должен расположить строки в алфавитном порядке, тогда...

public static class ExtensionOperation
{
    public static IEnumerable<String> AplhaLengthWise(
                                   this IEnumerable<String> names)
    {
        return names.OrderBy(a => a.Length).ThenBy(a => a);
    }
}

Ответ 6

Скопируйте, как это делает Microsoft:

public static class ExtensionOperation {
    // Handles anything queryable.
    public static IOrderedQueryable<string> AlphaLengthWise(this IQueryable<string> names) {
        return names.OrderBy(a => a.Length).ThenBy(a => a);
    }
    // Fallback method for non-queryable collections.
    public static IOrderedEnumerable<string> AlphaLengthWise(this IEnumerable<string> names) {
        return names.OrderBy(a => a.Length).ThenBy(a => a);
    }
}

Ответ 7

Вы хотите использовать IEnumerable<T> вместо T[]. Кроме того, вы не сможете использовать Length для T, так как не все типы имеют свойство Length. Вы можете изменить свой метод расширения на .OrderBy(a => a.ToString().Length)

Если вы знаете, что всегда будете иметь дело со строками, используйте IEnumerable<String>, а не IEnumerable<T>, и вы сразу получите доступ к свойству Length.