Typ anonimowy vs Typ dynamiczny

Jakie są rzeczywiste różnice pomiędzy typem anonimowym (var) w c# 3.0 A typem dynamicznym(dynamic), który pojawia się w c# 4.0?

Author: Marc Gravell, 2008-12-24

6 answers

Typ anonimowy to prawdziwy, generowany przez kompilator typ, który jest tworzony dla Ciebie. Dobrą rzeczą jest to, że kompilator może ponownie użyć tego typu później do innych operacji, które tego wymagają, ponieważ jest to POCO.

Moje rozumienie typów dynamicznych jest takie, że są one opóźnione, co oznacza, że CLR (lub DLR) oceni obiekt w czasie wykonywania, a następnie użyje typowania kaczki, aby zezwolić lub zablokować dostęp członka do obiektu.

Więc chyba różnica jest taka, że anonimowe typy są prawdziwymi POCOs, które kompilator może zobaczyć, ale można ich używać tylko, a typy dynamiczne są późnymi obiektami dynamicznymi.

 17
Author: Andrew Hare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-24 14:34:24

Wydaje się, że mieszasz trzy zupełnie różne, ortogonalne rzeczy:]}

  • statyczne vs. dynamiczne typowanie
  • manifest vs. implicit typowanie
  • named vs. anonymous typy
Te trzy aspekty są całkowicie niezależne, nie mają ze sobą nic wspólnego.

typowanie statyczne vs. dynamiczne odnosi się do , gdy sprawdzanie typu odbywa się: dynamiczne typowanie odbywa się na runtime, statyczne wpisywanie odbywa się przed runtime.

Manifest vs. implicit typowanie odnosi się do tego, czy typy są manifestem w kodzie źródłowym czy nie: typowanie manifestu oznacza, że programista musi zapisać typy w kodzie źródłowym, typowanie niejawne oznacza, że system typów sam je wylicza.

typy Named vs. anonymous odnoszą się do tego, czy typy mają nazwy czy nie.

Słowo kluczowe dynamic W C# 4.0 oznacza, że ta zmienna, parametr, metoda, pole, właściwość ... cokolwiek jest wpisywane dynamicznie , tzn. że jego typ będzie sprawdzany w czasie wykonywania. Wszystko, co nie jest wpisane jako dynamiczne, jest wpisywane statycznie. To, czy typ jest statyczny czy dynamiczny, decyduje nie tylko o tym, kiedy ma miejsce sprawdzenie typu, ale w C# 4.0 określa również, kiedy ma miejsce metoda dispatch. W C# metoda wysyłania jest wykonywana przed uruchomieniem, w oparciu o statyczne Typ (oczywiście z wyjątkiem podtypu runtime polimorfizm), natomiast na obiektach typowanych dynamicznie w C# 4.0 wysyłanie metody odbywa się w trybie runtime, na podstawie typu runtime.

Słowo kluczowe var W C# 3.0 oznacza, że zmienna lokalna będzie wpisana w domyśle , tzn. że zamiast programisty zapisującego Typ jawnie, system typów sam to wykona. Nie ma to nic wspólnego z dynamicznym pisaniem, przynajmniej w C# 3.0. Zmienna będzie mocno statycznie wpisywane tak, jakbyś sam zapisał Typ. Jest to tylko wygoda: na przykład, dlaczego miałbyś zapisywać wszystkie nazwy typów dwa razy w HashMap<int, string> foo = new HashMap<int, string>();, gdy system typów może wyraźnie dowiedzieć się, że foo jest HashMap<int, string>, więc zamiast tego piszesz var foo = new HashMap<int, string();. Pamiętaj, że nie ma w tym nic dynamicznego ani anonimowego. Typ jest statyczny i ma nazwę: HashMap<int, string>. Oczywiście w C # 4.0, jeśli system typów wykona, że prawa strona przypisanie jest dynamiczne, wtedy typ zmiennej po lewej stronie będzie dynamiczny.

An anonymous type W C# 3.0 oznacza, że ten typ nie ma nazwy. Cóż, w rzeczywistości, prawdziwe anonimowe typy wymagałyby wstecznie niezgodnej zmiany do Wspólnego Systemu typów, więc to, co W rzeczywistości dzieje się za kurtyną, to to, że kompilator wygeneruje bardzo długą, bardzo losową, unikalną i nielegalną nazwę dla typu i umieści tę nazwę wszędzie tam, gdzie jest to możliwe. pojawia się Typ anonimowy. Ale z punktu widzenia programisty, Typ nie ma nazwy. Dlaczego jest to przydatne? Cóż, czasami masz pośrednie wyniki, które potrzebujesz tylko na krótko, a następnie wyrzuć ponownie. Nadanie takim przejściowym typom nazwy własnej podniesie je do poziomu ważności, na który po prostu nie zasługują. Ale znowu, nie ma w tym nic dynamicznego.

Więc, jeśli Typ nie ma nazwy, jak programista może się do niego odnosić? Nie może! Przynajmniej nie bezpośrednio. To, co programista potrafi, to opisanie typu: ma on dwie właściwości, jedną o nazwie "nazwa" typu string, drugą o nazwie "id" typu int. Tego chcę, ale nie obchodzi mnie, jak to się nazywa.

Oto, gdzie kawałki zaczynają się łączyć. W C# musisz zadeklarować typy zmiennych lokalnych poprzez jawne zapisanie nazw typów. Ale jak możesz zapisać nazwę typu, który nie ma nazwy? Tu wkracza var: ponieważ od C# 3.0, to już nie jest prawda: nie musisz już zapisywać nazw, możesz również powiedzieć kompilatorowi, aby to rozgryzł. Tak więc, podczas gdy to, co napisałem w pierwszym akapicie powyżej, jest prawdą, że typowanie ukryte i typy anonimowe nie mają nic wspólnego z innymi, prawdą jest również, że typy anonimowe byłyby całkiem bezużyteczne bez typowania ukrytego.

Zauważ jednak, że nie jest odwrotnie: niejawne typowanie jest doskonale przydatne bez anonimowych typów. var foo = HashMap<int, string> makes perfect sens i nie ma anonimowego typu w zasięgu wzroku.

 84
Author: Jörg W Mittag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-24 20:14:43

Typ dynamic jest zasadniczo object, ale rozwiąże wszystkie wywołania metody / właściwości / operatora itp w czasie wykonywania za pośrednictwem DLR lub innego dostawcy (takiego jak reflection).

To bardzo przypomina VB z Option Strict Off, i sprawia, że jest bardzo wszechstronny do wywoływania COM lub typów DLR.

Nie ma nie ma sprawdzania typu w czasie kompilacji za pomocą dynamiki; co oczywiste, typy anonimowe są typami statycznymi, typami sprawdzanymi (można je zobaczyć w reflector, chociaż nie są ładne).

Dodatkowo, typy anonimowe mogą być obsługiwane wyłącznie przez kompilator; dynamic wymaga rozległej obsługi runtime - więc typy anonimowe są funkcją C#, ale dynamic będą w dużej mierze zaimplementowane przez. Net 4.0 (z pewnym wsparciem C# 4.0).

 16
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-24 17:22:08

Zobacz prezentację Andera tutaj:

Http://channel9.msdn.com/pdc2008/TL16/

HTM

 8
Author: Shim Tait,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-31 21:31:22

Jest trzy razy, z trzema aktorami - po jednym za każdym razem.

  • Design-time-programmer
  • Compile-time-C # compiler
  • Run-time -. NET runtime

Typy anonimowe są deklarowane i nazwane przez kompilator. Ta deklaracja jest oparta na specyfikacji programisty (w jaki sposób używał typu). Ponieważ te typy są nazwane po tym, jak programista opuścił proces, wydają się być bezimienne dla programisty, a więc "anonimowe".

  • The programista mówi: jakiś typ ma nazwę i adres
  • kompilator mówi: Istnieje Typ o nazwie xyz z właściwościami Name I Address oraz polami, oba ciągi znaków.
  • runtime mówi : nie mogę odróżnić xyz od dowolnego typu, który programista stworzył.

Dynamiczne pisanie w c# pozwala na wywołanie metod, które mogą lub nie mogą istnieć w czasie kompilacji. Jest to przydatne do wywołania Pythona lub javascript, które nie są kompilowane.

  • programista mówi: traktuj tę instancję samochodu jako typ dynamiczny. Teraz, Kwaku.
  • kompilator mówi: dynamiczne pisanie eh? musi być ok. Nie będę narzekać, bo nie mogę tego sprawdzić.
  • runtime próbuje zrobić instancję car, quack.
 6
Author: Amy B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-24 18:26:19

Nie ma to jak mały kod, aby wszystko wyjaśnić:

// anonymous types
var anonType = new {Id = "123123123", Name = "Goku", Age = 30, DateAdded = new DateTime()};
// notice we have a strongly typed anonymous class we can access the properties with
Console.WriteLine($"Anonymous Type: {anonType.Id} {anonType.Name} {anonType.Age} {anonType.DateAdded}");
// compile time error
//anonType = 100;

// dynamic types
dynamic dynType = 100.01m;
Console.WriteLine($"Dynamic type: {dynType}");
// it's ok to change the type however you want
dynType = new List<DateTime>();
Console.WriteLine($"Dynamic type: {dynType}");

// mix dynamic and anonymous
dynamic dynamicAnonymousType = new {Id = 8000, FirstName = "Goku", Gender = "male", IsSuperSaiyan = true};
// Wasn't sure this would work but it does! However, you lose intellisense on the FirstName so you have to type it manually.
Console.WriteLine($"FirstName: {dynamicAnonymousType.FirstName}");
dynamicAnonymousType = 100;
Console.WriteLine(dynamicAnonymousType);
// runtime error
Console.WriteLine($"Id: {dynamicAnonymousType.FirstName}");
 1
Author: goku_da_master,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-23 22:19:52