Buscar..


Observaciones

La palabra clave dynamic declara una variable cuyo tipo no se conoce en el momento de la compilación. Una variable dynamic puede contener cualquier valor y el tipo de valor puede cambiar durante el tiempo de ejecución.

Como se señaló en el libro "Metaprogramación en .NET", C # no tiene un tipo de respaldo para la palabra clave dynamic :

La funcionalidad habilitada por la palabra clave dynamic es un conjunto inteligente de acciones del compilador que emiten y usan objetos CallSite en el contenedor del sitio del ámbito de ejecución local. El compilador administra lo que los programadores perciben como referencias de objetos dinámicos a través de esas instancias de CallSite . Los parámetros, tipos de retorno, campos y propiedades que reciben un tratamiento dinámico en el momento de la compilación pueden marcarse con algunos metadatos para indicar que se generaron para uso dinámico, pero el tipo de datos subyacente para ellos siempre será System.Object .

Creando una variable dinámica

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

Dinámica de retorno

using System;

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

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

Creando un objeto dinámico con propiedades.

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

Manejo de tipos específicos desconocidos en tiempo de compilación

Los siguientes resultados equivalentes de salida:

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

La ventaja de la dinámica, es que agregar un nuevo Tipo para manejar solo requiere agregar una sobrecarga de DebugToStringInternal del nuevo tipo. También elimina la necesidad de convertirlo manualmente al tipo también.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow