Соглашения об именах методов C #: ToSomething против AsSomething


82

Когда я писал некоторые методы расширения для своих объектов бизнес-логики, я пришел к вопросу о переименовании методов преобразования. someObject.ToAnotherObject()отлично подошли бы к широко используемым object.ToString().

Однако LINQ, например, смешивает оба варианта, и я не могу найти между ними разницы. ToDictionary(), ToList(), AsParallel(), AsQueryable(), ...

В чем разница между этими двумя соглашениями об именах и что мне нужно знать, чтобы решить, использовать ли их для моих собственных классов?

Ответы:


91

ToDictionaryи ToListимеют префикс, Toпотому что они не обязательно сохраняют структурную идентичность исходной коллекции или ее свойства.

  • Преобразование a List<T>в a Dictionary<K, V>создает коллекцию с совершенно новой структурой.
  • Преобразование a HashSet<T>в a List<T>устраняет свойство уникальности множеств.

Методы с префиксом Asне делают ничего из этого - они просто предоставляют альтернативное представление исходной коллекции. Они его обогащают.


41
Итак, на яблоке я мог позвонить, .AsCleanApple()так как мне нужно только его помыть, и .ToFruitSalad()потому что мой нож изменил бы структуру яблока‽
Physikbuddha

3
@Physikbuddha В принципе, да.
MKII

38
@Physikbuddha Мне кажется, что- AsCleanAppleто изменится в яблоке. Лучшая аналогияAsFruit
dcastro

4
.AsCleanAppleSource()превратит то, что было источником яблок, в то, что было источником чистых яблок; добавляя этап промывки, если необходимо, но, возможно, ничего не делая, если яблоки уже известны как чистые. .ToPunnet()получит доступ к этому источнику и даст вам корзину яблок.
Джон Ханна,

2
Это не совсем так, но в целом вы можете рассматривать «AsXXX ()» как преобразование, а «ToXXX ()» - как преобразование.
nateirvin

26

В Linq ToXXXвсе методы выполняют запрос и создают новый объект из результатов, в то время как AsXXXметоды создают новый запрос, который в чем-то отличается. Это может быть тот же объект, но доступ к нему осуществляется через другой интерфейс ( AsEnumerable()делает это), или это может быть новый объект, который изменяет функциональность (другие методы делают это, хотя некоторые проверяют, могут ли они просто вернуть данный объект, например, AsQueryable()будут вернуть, sourceесли он IQueryable<T>уже реализован , или создать новый в EnumerableQuery<TElement>противном случае).


that alters how the functionality- howНенужно или должна быть следующая часть заявления?
Капол

@Kapol нет, просто опечатка из-за одновременного написания и набора текста.
Джон Ханна,

Я думаю, что это правильный ответ, т.е. активная или статическая проекция исходного экземпляра. ToXXX()проецирует данные без отношения к оригиналу. AsXXX()поддерживает активное отношение к оригиналу (по крайней мере, в обсуждаемых нами примерах Enumerable / Queryable).
Тим Медора

+1 для ToXXX execute the queryи AsXXX produce a new query. Звучит правильно из того, что я читал о LINQ, и MSDN, похоже, подтверждает ToXXX , но мне интересно, есть ли у кого-нибудь источник, все ли AsXXXметоды являются отложенным выполнением?
brichins

1
@brichins есть ли даже осмысленный способ сказать «все», учитывая, что любой из нас может прийти с новым провайдером, который добавляет новый AsXXXповерх тех, которые присущи Linq (например, AsParallelдобавленный PLinq, AsNoTrackingпредоставленный Entity Framework, и так далее). Конечно, ядро ​​linq - это то, что определяется Queryableи Enumerable, и оба этих класса следуют этому соглашению. Большинство дополнений делают это до такой степени, что "все", вероятно, будет правильным, но оно слишком открыто, чтобы гарантировать, что всегда будет правильным (хотя я считаю любое нарушение недостатком дизайна).
Джон Ханна,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.