Неверно ли расширение типа для предоставления метода расширения для закрытого члена?

1

Недавно я был взят за расширение пользовательского класса, чтобы выставить метод расширения LINQ для частного участника, например:

public virtual T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
    return _someDbSet.FirstOrDefault(predicate);
}

Некоторые члены команды сказали, что это плохо. Приведенное объяснение было чем-то вроде строки: поскольку внутренний метод является методом расширения, внешний должен быть также.

(Почему) это так плохо?

  • 5
    Это не метод расширения.
  • 0
    Это то, что делает это плохо? Почему? (Обратите внимание, что внутренний FirstOrDefault является методом расширения.)
Показать ещё 4 комментария
Теги:
linq
extension-methods

2 ответа

1
Лучший ответ

Нет большой проблемы при добавлении метода с тем же именем, что и существующий метод расширения, если он "переопределяет" функциональность этого метода расширения или сигнатуры несовместимы друг с другом (или если метод расширения может " t применяется к этому конкретному классу).

Если эти правила не применяются или вы намерены использовать их оба, это может быть действительно запутанным, какой метод вызывается в конце. Это может привести к ошибкам, поэтому я не советую использовать метод с тем же именем, что и метод расширения.

  • 0
    Я согласен и добавляю, что переименование метода возможно в любом случае. FirstOrDefault имеет смысл, только если класс логически является коллекцией (но я предполагаю, что это немного больше, чем просто)
  • 0
    @YoryeNathan: Что делать, если класс служит какой-то коллекцией (может быть, он выбирает первую строку из БД, кто знает?). иметь метод с именем FirstOrDefault прекрасно.
Показать ещё 1 комментарий
0

Приведенное объяснение было чем-то вроде строки: поскольку внутренний метод является методом расширения, внешний должен быть также.

Если это был аргумент, то это полная глупость. В логическом завершении мы не могли назвать каких-либо статических членов в членах экземпляра (поскольку методы расширения - это просто статические методы с некоторым синтаксическим сахаром, чтобы они выглядели как методы экземпляра для первого аргумента). Примените это последовательно, и вы скоро закончите либо без статических методов вообще, либо без каких-либо объектов.

Здесь есть немного проблемы:

публичный виртуальный T FirstOrDefault (предикат Expression>)

FirstOrDefault - широко используемый метод расширения. Таким образом, у нас есть идея, что он собирается делать, когда мы это называем.

Если класс действует как коллекция, которая обертывает _someDbSet то этот метод бессмыслен; мы можем просто использовать FirstOrDefault который уже существует.

Если класс не действует как коллекция, которая обертывает _someDbSet тогда этот метод может быть запутанным, поскольку он не будет действовать так, как мы ожидали бы, чтобы известный FirstOrDefault действовал.

Если класс IEnumerable или IQueryable и FirstOrDefault не делают то же самое, что и FirstOrDefault расширения FirstOrDefault, тогда это может быть очень запутанным, потому что одно и то же имя участника FirstOrDefault бы другое поведение в зависимости от того, как ссылался объект, и что только очень редко хорошая вещь.

И наоборот, если бы у нас был FirstOrDefault экземпляра FirstOrDefault который делал то же самое, что и FirstOrDefault, в противном случае, но делал бы это намного эффективнее, тогда это случай, когда метод маски экземпляра метода расширения - это очень хорошо; нет никакой разницы в поведении в отношении вызывающего кода, просто повышение производительности, которое является "бесплатным" до того, как этот код вызова идет, поскольку он написан точно так же, как и в любом случае.

  • 0
    Это действительно просто FirstOrDefault существующего FirstOrDefault , но для члена, который является частным. Оборачивая это как это выставляет это.
  • 0
    Ну да, для этого и нужны публичные участники; выставлять операции на частное государство.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню