2013-01-01 15 views
10

Napisałem tę metodę rozszerzenia:Konwertuj na IEnumerable <dynamic>?

public static class A 
{ 
public static IEnumerable<dynamic> AsDynamic<T>(this IEnumerable<T> f) 
    { 
     foreach (var element in f) 
     { 
       yield return (dynamic) element; 
     } 
    } 
} 

i przetestowane go:

List<int> l = new List<int>(){1,2,3}; 
Console.WriteLine (l.AsDynamic().GetType()); 

jednak wyjście: typeof (IEnumerable<Object>)

  • Dlaczego nie jest typeof (IEnumerable<dynamic>)?

  • Jak mogę to polubić?

+2

["W większości przypadków działa tak, jak ma obiekt typu."] (Http://msdn.microsoft.com/en-us/library/dd264736.aspx) –

+1

Brak typu 'dynamic' w środowisku wykonawczym są one po prostu wpisywane jako obiekt, a informacje o powiązaniu metody są wyprowadzane w każdej witrynie wywołania z użyciem zmiennej dynamicznej. – Lee

Odpowiedz

21

Myślę, że masz nieporozumienie co oznacza dynamic. Zasadniczo, gdy powiesz kompilatorowi, że typ obiektu to dynamic, "obiecujesz", że obiekt w czasie wykonywania będzie obsługiwał dowolne metody lub właściwości, które wywołasz, w zamian za kompilator nie narzekający na w czasie kompilacji. Obiecujesz także, że poniesiesz konsekwencje, jeśli złamiesz swoją obietnicę.

Kiedy mówimy, że obiekt jest dynamic, kompilator nie może przyjąć założeń dotyczących typu, więc używa object, wiedząc, że wszystko może być przechowywane jako object. Wykonując IEnumerable<dynamic> staje IEnumerable<object>, z jedną istotną różnicą: można wywołać dowolną metodę na jej elementów, a kompilator nie powie słowa:

IEnumerable<SomeType> original = ... 
foreach (dynamic x in original.AsDynamic()) { // Using your method 
    Console.WriteLine(x.SomeUnsupportedMethod()); // The compiler is silent! 
} 

Od original.AsDynamic() daje sekwencję dynamic obiektów kompilator nie narzeka na Twój telefon pod numer SomeUnsupportedMethod.Jeśli ta metoda rzeczywiście nie jest obsługiwana w środowisku wykonawczym, program ulegnie awarii; jeśli metoda jest faktycznie obsługiwana przez elementy SomeType, nie będzie awarii, a metoda zostanie wywołana.

Wszystko to zrobi dla ciebie dynamic; statycznie, "element zastępczy" pozostanie object, a typeof powie Ci tyle. Ale dokładne możliwości obiektu (jego metody i właściwości) nie będą badane aż do czasu wykonania.

+1

Jak rozumiem z dyskusji w komentarzach do innej odpowiedzi, pisanie 'typeof (IEnumerable )' jest faktycznie legalne (ale nieprzydatne!) W języku C#, ale tworzy ten sam typ środowiska wykonawczego co 'typeof (IEnumerable )'. Jednakże 'typeof (dynamic)' nie jest dozwolone jako synonim dla 'typeof (object)'. Nawiasem mówiąc, 'GetType()' nigdy nie zwróci oczywiście typu interfejsu, więc oryginalny plakat nie był dokładny. –

+0

@JeppeStigNielsen http://i.stack.imgur.com/9C4sD.jpg –

+0

@RoyiNamir Nie jestem pewien, czy rozumiem twój zrzut ekranu (nie znam LINQPada). Dwie linie mają inną typografię. Nie są wyjściami dwóch wywołań metod "WriteLine". Funkcja 'GetType()' zwraca obiekt 'RuntimeType', w pierwszej' WriteLine' wywoływana jest metoda 'ToString()'. Typ będzie generowanym typem (klasa o dziwnej nazwie z '<', '>' i znakami '__' w nim), ponieważ masz blok iteratora (' return return'). Spróbuj tego: 'if (l.AsDynamic(). GetType() == typeof (IEnumerable )) throw new Exception (" Jeppe było złe! ");' –

0

Wypróbuj metodę przedłużania Linq Cast(). Ale nie jestem pewien, czy zadziała z dynamiką.

0

dynamic Ponieważ nie jest typem

Console.WriteLine(typeof(dynamic)); // error 

dynamiczny tylko rozwiązuje rzeczywisty typ w czasie wykonywania

+0

MSDN odnosi się również do "typu": [Visual C# 2010 wprowadza nowy typ, dynamiczny] (http://msdn.microsoft.com/en-us/library/dd264736.aspx) –

+0

@ Some1.Kill.The. DJ - Próba użycia 'typeof (dynamic)' powoduje błąd kompilacji, "Operator typeof nie może być użyty w typie dynamicznym." – Lee

+0

@Le "dynamiczny" jest typem, który nie jest znany w czasie wykonywania. Dynamiczny i obiekt są podobne, z wyjątkiem dynamicznego pozwala robić rzeczy, które nie mogą być wykonane w czasie kompilacji. – Anirudha

1

Zgodnie z projektem, wykonawczego Wiązania zachowują się podobnie jak możliwie statycznej wiążącego.

Więc typ środowiska wykonawczego będzie typeof (IEnumerable<Object>)

typ statyczny byłoby typeof (IEnumerable<dynamic>)

także

traktuje uruchomieniowe to prawda koncepcyjnie

typeof(object)==typeof(dynamic) 

Więc

dynamiczna ty pe jest jak obiekt, z tym wyjątkiem, że pozwala ci używać go w sposób, który nie jest znany podczas kompilacji.

Powiązane problemy