Ricerca…


Osservazioni

La parola chiave dynamic dichiara una variabile il cui tipo non è noto al momento della compilazione. Una variabile dynamic può contenere qualsiasi valore e il tipo di valore può cambiare durante il runtime.

Come notato nel libro "Metaprogramming in .NET", C # non ha un tipo di supporto per la parola chiave dynamic :

La funzionalità abilitata dalla parola chiave dynamic è un insieme intelligente di azioni del compilatore che emettono e utilizzano oggetti CallSite nel contenitore del sito dell'ambito di esecuzione locale. Il compilatore gestisce ciò che i programmatori percepiscono come riferimenti di oggetti dinamici attraverso quelle istanze di CallSite . I parametri, i tipi di ritorno, i campi e le proprietà che ottengono il trattamento dinamico in fase di compilazione possono essere contrassegnati con alcuni metadati per indicare che sono stati generati per l'uso dinamico, ma il tipo di dati sottostante per loro sarà sempre System.Object .

Creare una variabile dinamica

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

Tornando dinamico

using System;

public static void Main()
{
    var value = GetValue();
    Console.WriteLine(value);
    // dynamics are useful!
}

private static dynamic GetValue()
{
    return "dynamics are useful!";
}

Creazione di un oggetto dinamico con proprietà

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

Gestione di tipi specifici sconosciuti al momento della compilazione

I seguenti risultati equivalenti di output:

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())}";
    }
}

Il vantaggio per la dinamica, è l'aggiunta di un nuovo tipo da gestire richiede solo l'aggiunta di un sovraccarico di DebugToStringInternal del nuovo tipo. Elimina anche la necessità di eseguirne manualmente il cast nel tipo.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow