Поиск…


замечания

dynamic ключевое слово объявляет переменную, тип которой неизвестен во время компиляции. dynamic переменная может содержать любое значение, а тип значения может изменяться во время выполнения.

Как отмечено в книге «Метапрограммирование в .NET», C # не имеет типа поддержки для dynamic ключевого слова:

Функциональность, включенная ключевым словом dynamic является умным набором действий компилятора, которые испускают и используют объекты CallSite в контейнере сайта области локального выполнения. Компилятор управляет тем, что программисты воспринимают как динамические ссылки на объекты через эти экземпляры CallSite . Параметры, типы возвращаемых данных, поля и свойства, которые получают динамическую обработку во время компиляции, могут быть отмечены некоторыми метаданными, чтобы указать, что они были созданы для динамического использования, но базовый тип данных для них всегда будет System.Object .

Создание динамической переменной

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

Возвращение динамического

using System;

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

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

Создание динамического объекта со свойствами

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

Обработка определенных типов, неизвестных во время компиляции

Следующие эквивалентные результаты:

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

Преимущество динамического, добавляя новый тип для обработки, просто требует добавления перегрузки DebugToStringInternal нового типа. Также устраняет необходимость вручную отбрасывать его на тип.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow