Używanie dynamicznego typu

Typ dynamic jest typem statycznym, ale obiekt typu dynamic pomija sprawdzanie typu statycznego. W większości przypadków działa tak, jakby miał typ object. Kompilator zakłada, że element obsługuje dowolną dynamic operację. W związku z tym nie musisz określać, czy obiekt pobiera jego wartość z interfejsu API COM, z języka dynamicznego, takiego jak IronPython, z modelu DOM (DOCUMENT Object Model), odbicia lub z innego miejsca w programie. Jeśli jednak kod nie jest prawidłowy, błędy pojawią się w czasie wykonywania.

Jeśli na przykład metoda exampleMethod1 wystąpienia w poniższym kodzie ma tylko jeden parametr, kompilator rozpoznaje, że pierwsze wywołanie metody , nie jest prawidłowe, ec.exampleMethod1(10, 4)ponieważ zawiera dwa argumenty. Wywołanie powoduje błąd kompilatora. Kompilator nie sprawdza drugiego wywołania metody , dynamic_ec.exampleMethod1(10, 4)ponieważ typ dynamic_ec to dynamic. W związku z tym nie jest zgłaszany żaden błąd kompilatora. Jednak błąd nie jest zwracany w nieskończoność. Pojawia się on w czasie wykonywania i powoduje wyjątek czasu wykonywania.

static void Main(string[] args)
{
    ExampleClass ec = new ExampleClass();
    // The following call to exampleMethod1 causes a compiler error
    // if exampleMethod1 has only one parameter. Uncomment the line
    // to see the error.
    //ec.exampleMethod1(10, 4);

    dynamic dynamic_ec = new ExampleClass();
    // The following line is not identified as an error by the
    // compiler, but it causes a run-time exception.
    dynamic_ec.exampleMethod1(10, 4);

    // The following calls also do not cause compiler errors, whether
    // appropriate methods exist or not.
    dynamic_ec.someMethod("some argument", 7, null);
    dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
    public ExampleClass() { }
    public ExampleClass(int v) { }

    public void exampleMethod1(int i) { }

    public void exampleMethod2(string str) { }
}

Rolą kompilatora w tych przykładach jest spakowanie razem informacji o tym, co każda instrukcja proponuje zrobić dla dynamic obiektu lub wyrażenia. Środowisko uruchomieniowe sprawdza przechowywane informacje i dowolną instrukcję, która nie jest prawidłowa, powoduje wyjątek czasu wykonywania.

Wynikiem najbardziej dynamicznych operacji jest sam dynamic. Jeśli na przykład wskaźnik myszy testSum zostanie użyty w poniższym przykładzie, funkcja IntelliSense wyświetli test dynamiczny typu (zmienna lokalna).

dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

Operacje, w których wynik nie dynamic obejmuje:

  • Konwersje z dynamic na inny typ.
  • Wywołania konstruktora, które zawierają argumenty typu dynamic.

Na przykład typ testInstance w następującej deklaracji to ExampleClass, a nie dynamic:

var testInstance = new ExampleClass(d);

Konwersje

Konwersje między obiektami dynamicznymi i innymi typami są łatwe. Konwersje umożliwiają deweloperowi przełączanie się między zachowaniem dynamicznym i niedynamicznym.

Dowolny można przekonwertować na dynamic niejawnie, jak pokazano w poniższych przykładach.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

Z drugiej strony można dynamicznie stosować dowolną niejawną konwersję do dowolnego wyrażenia typu dynamic.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

Rozpoznawanie przeciążenia z argumentami typu dynamicznego

Rozpoznawanie przeciążeń występuje w czasie wykonywania zamiast w czasie kompilacji, jeśli co najmniej jeden argument w wywołaniu metody ma typ dynamic, lub jeśli odbiornik wywołania metody jest typu dynamic. W poniższym przykładzie, jeśli jedyna dostępna exampleMethod2 metoda przyjmuje argument ciągu, wysyłanie d1 jako argument nie powoduje błędu kompilatora, ale powoduje wyjątek czasu wykonywania. Rozpoznawanie przeciążenia kończy się niepowodzeniem w czasie wykonywania, ponieważ typ d1 czasu wykonywania to int, i exampleMethod2 wymaga ciągu.

// Valid.
ec.exampleMethod2("a string");

// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);

Środowisko uruchomieniowe języka dynamicznego

Środowisko uruchomieniowe języka dynamicznego (DLR) udostępnia infrastrukturę, która obsługuje dynamic typ języka C#, a także implementację języków programowania dynamicznego, takich jak IronPython i IronRuby. Aby uzyskać więcej informacji na temat biblioteki DLR, zobacz Dynamic Language Runtime Overview (Omówienie środowiska uruchomieniowego języka dynamicznego).

COM interop

Wiele metod COM umożliwia zmianę typów argumentów i zwracanie typu przez wyznaczenie typów jako object. Międzyoperacyjna com wymaga jawnego rzutowania wartości w celu koordynowania z silnie typinymi zmiennymi w języku C#. Jeśli kompilujesz przy użyciu opcji EmbedInteropTypes (opcje kompilatora języka C#), wprowadzenie dynamic typu umożliwia traktowanie wystąpień object w podpisach COM tak, jakby były typu dynamic, a tym samym uniknąć dużej części rzutowania. Aby uzyskać więcej informacji na temat używania dynamic typu z obiektami COM, zobacz artykuł How to access Office interop objects by using C# features (Jak uzyskać dostęp do obiektów międzyoperacyjnych pakietu Office przy użyciu funkcji języka C#).

Nazwa opis
dynamic Opisuje użycie słowa kluczowego dynamic .
Przegląd środowiska uruchomieniowego języka dynamicznego Zawiera omówienie biblioteki DLR, czyli środowiska uruchomieniowego, które dodaje zestaw usług dla języków dynamicznych do środowiska uruchomieniowego języka wspólnego (CLR).
Przewodnik: tworzenie i używanie obiektów dynamicznych Zawiera instrukcje krok po kroku dotyczące tworzenia niestandardowego obiektu dynamicznego oraz tworzenia projektu, który uzyskuje IronPython dostęp do biblioteki.