Använda dynamisk typ
Typen dynamic
är en statisk typ, men ett objekt av typen dynamic
kringgår kontrollen av statisk typ. I de flesta fall fungerar den som om den har typen object
. Kompilatorn förutsätter att ett dynamic
element stöder alla åtgärder. Därför behöver du inte avgöra om objektet hämtar sitt värde från ett COM-API, från ett dynamiskt språk som IronPython, från HTML Document Object Model (DOM), från reflektion eller från någon annanstans i programmet. Men om koden inte är giltig visas fel vid körning.
Om instansmetoden exampleMethod1
i följande kod till exempel bara har en parameter, identifierar kompilatorn att det första anropet till metoden, ec.exampleMethod1(10, 4)
, inte är giltigt eftersom det innehåller två argument. Anropet orsakar ett kompilatorfel. Kompilatorn kontrollerar inte det andra anropet till metoden, dynamic_ec.exampleMethod1(10, 4)
, eftersom typen av dynamic_ec
är dynamic
. Därför rapporteras inget kompilatorfel. Felet undfly dock inte meddelandet på obestämd tid. Det visas vid körning och orsakar ett körningsfel.
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) { }
}
Kompilatorns roll i de här exemplen är att paketera information om vad varje instruktion föreslår att göra med dynamic
objektet eller uttrycket. Körningen undersöker den lagrade informationen och alla instruktioner som inte är giltiga orsakar ett körningsundundatag.
Resultatet av de mest dynamiska åtgärderna är i sig .dynamic
Om du till exempel vilar muspekaren över användningen av testSum
i följande exempel visar IntelliSense typen (lokal variabel) dynamisk testSumma.
dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);
Åtgärder där resultatet inte dynamic
ingår:
- Konverteringar från
dynamic
till en annan typ. - Konstruktoranrop som innehåller argument av typen
dynamic
.
Till exempel är typen av testInstance
i följande deklaration , inte dynamic
:ExampleClass
var testInstance = new ExampleClass(d);
Omvandlingar
Konverteringar mellan dynamiska objekt och andra typer är enkla. Med konverteringar kan utvecklaren växla mellan dynamiskt och icke-dynamiskt beteende.
Du kan konvertera valfri till dynamic
implicit, som du ser i följande exempel.
dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
Däremot kan du dynamiskt tillämpa alla implicita konverteringar på alla uttryck av typen dynamic
.
int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;
Överbelastningsmatchning med argument av typen dynamisk
Överbelastningsmatchning sker vid körning i stället för vid kompileringstid om ett eller flera av argumenten i ett metodanrop har typen dynamic
, eller om mottagaren av metodanropet är av typen dynamic
. I följande exempel, om den enda tillgängliga exampleMethod2
metoden tar ett strängargument, orsakar sändning d1
som argumentet inte ett kompilatorfel, men det orsakar ett körningsfel. Överlagringsupplösningen misslyckas vid körning eftersom körningstypen d1
är int
, och exampleMethod2
kräver en sträng.
// 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);
Körning av dynamiskt språk
DLR (Dynamic Language Runtime) tillhandahåller den infrastruktur som stöder dynamic
typen i C#, och även implementeringen av dynamiska programmeringsspråk som IronPython och IronRuby. Mer information om DLR finns i Översikt över dynamisk språkkörning.
COM-interop
Många COM-metoder tillåter variation i argumenttyper och returtyp genom att ange typerna som object
. COM-interop kräver explicit gjutning av värdena för att samordna med starkt skrivna variabler i C#. Om du kompilerar med hjälp av alternativet EmbedInteropTypes (C#Compiler Options) kan du med introduktionen dynamic
av typen behandla förekomsterna av object
i COM-signaturer som om de var av typen dynamic
och därmed undvika mycket av gjutningen. Mer information om hur du använder dynamic
typen med COM-objekt finns i artikeln Om hur du kommer åt Office-interop-objekt med hjälp av C#-funktioner.
Relaterade artiklar
Title | Description |
---|---|
dynamisk | Beskriver användningen av nyckelordet dynamic . |
Översikt över Dynamic Language Runtime | Ger en översikt över DLR, som är en körningsmiljö som lägger till en uppsättning tjänster för dynamiska språk i CLR (Common Language Runtime). |
Genomgång: Skapa och använda dynamiska objekt | Innehåller stegvisa instruktioner för att skapa ett anpassat dynamiskt objekt och för att skapa ett projekt som har åtkomst till ett IronPython bibliotek. |