Konwencje nazewnictwa metod języka C #: ToSomething vs. AsSomething

82

Kiedy pisałem kilka metod rozszerzających dla moich obiektów logiki biznesowej, doszedłem do kwestii zmiany nazw metod konwersji. someObject.ToAnotherObject()pasowałby dobrze z szeroko stosowanym object.ToString().

Jednak LINQ, na przykład, miesza oba warianty i nie mogę znaleźć między nimi różnicy. ToDictionary(), ToList(), AsParallel(), AsQueryable(), ...

Jakie są różnice między tymi dwiema konwencjami nazewnictwa i co powinienem wiedzieć, aby zdecydować, czy użyć dla własnych klas?

Physikbuddha
źródło

Odpowiedzi:

91

ToDictionaryi ToListsą poprzedzone prefiksem, Toponieważ niekoniecznie zachowują strukturalną tożsamość oryginalnej kolekcji lub jej właściwości.

  • Przekształcenie a List<T>w a Dictionary<K, V>tworzy kolekcję o zupełnie nowej strukturze.
  • Przekształcenie a HashSet<T>w a List<T>usuwa wyjątkowość zbiorów.

Metody z prefiksem Asnie wykonują żadnej z tych rzeczy - po prostu zapewniają alternatywny widok oryginalnej kolekcji. Wzbogacają to.

dcastro
źródło
41
Tak więc, na jabłko mógłbym nazwać .AsCleanApple()odkąd tylko trzeba go umyć, a .ToFruitSalad()ponieważ mój nóż zmieni strukturę apple‽
Physikbuddha
3
@Physikbuddha Zasadniczo tak.
MKII
38
@Physikbuddha Wydaje mi się, AsCleanAppleże zmieni coś w jabłku. Lepszą analogią mogłoby byćAsFruit
dcastro
4
.AsCleanAppleSource()zmieni coś, co było źródłem jabłek, w coś, co było źródłem czystych jabłek; dodanie etapu mycia, jeśli to konieczne, ale być może nie robiąc nic, jabłka były już znane jako czyste. .ToPunnet()uzyskałby dostęp do tego źródła i dałby ci punnet jabłek.
Jon Hanna
2
Nie jest to do końca prawdą, ale generalnie można traktować „AsXXX ()” jako rzut, a „ToXXX ()” jako konwersję.
nateirvin
26

W Linq ToXXXwszystkie metody wykonują zapytanie i tworzą nowy obiekt na podstawie wyników, podczas gdy AsXXXmetody generują nowe zapytanie, które jest w pewien sposób inne. Może to być ten sam obiekt, ale dostępne za pośrednictwem innego interfejsu ( AsEnumerable()robi to) lub może to być nowy obiekt, który zmienia funkcjonalność (inne sposoby to zrobić, choć niektórzy sprawdzić, czy może po prostu wrócić danego obiektu, np AsQueryable()wola powrót, sourcejeśli IQueryable<T>już implementuje , lub w EnumerableQuery<TElement>przeciwnym razie utwórz nowy ).

Jon Hanna
źródło
that alters how the functionality- Czy jest howniepotrzebne, czy też powinna być kolejna część oświadczenia?
Kapol
@Kapol nie, tylko literówka spowodowana tworzeniem i pisaniem w tym samym czasie.
Jon Hanna
Myślę, że to jest prawidłowa odpowiedź, tj. Aktywna kontra statyczna projekcja oryginalnej instancji. ToXXX()wyświetla dane bez związku z oryginałem. AsXXX()utrzymuje aktywny związek z oryginałem (przynajmniej w przykładach Enumerable / Queryable, które omawiamy).
Tim Medora
+1 dla ToXXX execute the queryi AsXXX produce a new query. Brzmi dobrze z tego, co przeczytałem w LINQ, a MSDN wydaje się potwierdzać ToXXX , ale zastanawiam się, czy ktoś ma źródło, czy wszystkie AsXXX metody są odroczone?
brichins
1
@brichins czy istnieje nawet sensowny sposób na powiedzenie „wszystko”, biorąc pod uwagę, że każdy z nas mógłby przyjść z nowym dostawcą, który dodaje nowego AsXXXdo tych właściwych dla Linq (np. AsParalleldodany przez PLinq, AsNoTrackingdostarczony przez Entity Framework, i tak dalej). Z pewnością rdzeniem linq jest to, co jest zdefiniowane przez Queryablei Enumerable, a obie te klasy są zgodne z tą konwencją. Większość dodatków robi to do tego stopnia, że ​​„wszystko” prawdopodobnie byłoby poprawne, ale jest zbyt otwarte, aby zagwarantować, że zawsze będzie poprawne (chociaż uważam, że każde uszkodzenie jest błędem projektowym).
Jon Hanna