C# Language
Dynamisch type
Zoeken…
Opmerkingen
Het dynamic
trefwoord declareert een variabele waarvan het type niet bekend is tijdens het compileren. Een dynamic
variabele kan elke waarde bevatten en het type waarde kan tijdens runtime veranderen.
Zoals opgemerkt in het boek "Metaprogrammering in .NET" heeft C # geen type back-up voor het dynamic
trefwoord:
De functionaliteit die wordt ingeschakeld door het
dynamic
trefwoord is een slimme set compileracties dieCallSite
objecten uitzenden en gebruiken in deCallSite
van het lokale uitvoeringsbereik. De compiler beheert wat programmeurs waarnemen als dynamische objectverwijzingen via dieCallSite
instanties. De parameters, retourtypen, velden en eigenschappen die tijdens het compileren dynamisch worden behandeld, kunnen worden gemarkeerd met enkele metagegevens om aan te geven dat ze zijn gegenereerd voor dynamisch gebruik, maar het onderliggende gegevenstype voor hen zal altijdSystem.Object
.
Een dynamische variabele maken
dynamic foo = 123;
Console.WriteLine(foo + 234);
// 357 Console.WriteLine(foo.ToUpper())
// RuntimeBinderException, since int doesn't have a ToUpper method
foo = "123";
Console.WriteLine(foo + 234);
// 123234
Console.WriteLine(foo.ToUpper()):
// NOW A STRING
Terugkerende dynamiek
using System;
public static void Main()
{
var value = GetValue();
Console.WriteLine(value);
// dynamics are useful!
}
private static dynamic GetValue()
{
return "dynamics are useful!";
}
Een dynamisch object met eigenschappen maken
using System;
using System.Dynamic;
dynamic info = new ExpandoObject();
info.Id = 123;
info.Another = 456;
Console.WriteLine(info.Another);
// 456
Console.WriteLine(info.DoesntExist);
// Throws RuntimeBinderException
Omgaan met specifieke typen die onbekend zijn tijdens het compileren
De volgende outputequivalentresultaten:
class IfElseExample
{
public string DebugToString(object a)
{
if (a is StringBuilder)
{
return DebugToStringInternal(a as StringBuilder);
}
else if (a is List<string>)
{
return DebugToStringInternal(a as List<string>);
}
else
{
return a.ToString();
}
}
private string DebugToStringInternal(object a)
{
// Fall Back
return a.ToString();
}
private string DebugToStringInternal(StringBuilder sb)
{
return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}";
}
private string DebugToStringInternal(List<string> list)
{
return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t" + string.Join(Environment.NewLine + "\t", list.ToArray())}";
}
}
class DynamicExample
{
public string DebugToString(object a)
{
return DebugToStringInternal((dynamic)a);
}
private string DebugToStringInternal(object a)
{
// Fall Back
return a.ToString();
}
private string DebugToStringInternal(StringBuilder sb)
{
return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}";
}
private string DebugToStringInternal(List<string> list)
{
return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t" + string.Join(Environment.NewLine + "\t", list.ToArray())}";
}
}
Het voordeel van de dynamiek is dat het toevoegen van een nieuw te verwerken type alleen een overbelasting van DebugToStringInternal van het nieuwe type vereist. Het elimineert ook de noodzaak om het ook handmatig naar het type te casten.