Правила іменування методів C #: ToSomething проти AsSomething


82

Коли я писав деякі методи розширення для своїх об’єктів бізнес-логіки, я прийшов до питання перейменування методів перетворення. someObject.ToAnotherObject()підійде до широко використовуваних object.ToString().

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

Які відмінності між цими двома умовами іменування та що я повинен знати, щоб вирішити, чи використовувати для власних класів?

Відповіді:


91

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

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

Методи з префіксом Asне виконують жодної з цих речей - вони просто надають альтернативний вигляд оригінальної колекції. Вони його збагачують.


41
Отже, на яблуко я міг би зателефонувати, .AsCleanApple()оскільки мені потрібно лише помити його, і .ToFruitSalad()тому, що мій ніж змінить структуру яблука‽
Фізікбудда,

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.