Подтвердить что ты не робот

Есть ли способ проверить, является ли переменная динамической?

Следующий фрагмент кода всегда будет возвращать true, если переменная v равна null:

v is dynamic

и следующий тест не будет компилироваться ( "Оператор typeof не может использоваться для динамического типа" ):

v.GetType() == typeof(dynamic)

Итак, есть ли способ проверить, есть ли переменная dynamic?

4b9b3361

Ответ 1

Во-первых, вам нужно отделить переменную и объект. Переменная динамическая , если она определена как dynamic. Вот и все. Больше ничего. Поле или свойство будут аннотированы с помощью атрибута [Dynamic], то есть

public dynamic Foo {get;set;}

на самом деле:

[Dynamic]
public object Foo {get;set;}

Это в основном выступает как приглашение для компилятора получить доступ к объекту через API dynamic, а не через API OOP.

Объект поддерживает полные возможности dynamic, если он реализует IDynamicMetaObjectProvider - однако к этому объекту можно получить доступ как через API dynamic, так и через обычный API ООП (он может иметь оба). Точно так же объект, который не реализует IDynamicMetaObjectProvider, может быть доступен через API (но: только публичные члены будут доступны через dynamic).

Ответ 2

Нет типа CLR, называемого dynamic. Компилятор С# делает все значения dynamic типа object, а затем вызывает код обязательной привязки, чтобы выяснить, как с ними справиться. Если был использован dynamic, он будет отображаться как object.

Но вы можете проверить, имеет ли экземпляр тип IDynamicMetaObjectProvider, или вы можете проверить, реализует ли тип IDynamicMetaObjectProvider

Ответ 3

В динамике С# нет проверки времени выполнения, и она будет иметь тип другой стороны символа =. Однако GetType - это оценка времени выполнения, поэтому вы всегда будете получать объявленный тип, а не динамический.

Вы можете прочитать немного больше здесь: http://msdn.microsoft.com/en-us/magazine/gg598922.aspx

Ответ 4

Всегда будет существовать тип времени выполнения, как говорили другие.

Существует ошибка для обнаружения локальных переменных, полагаясь на то, что динамические переменные не поддерживают методы расширения.

static void DummyDynamicTest<T>(this T t) //extension method
{

}

dynamic test = 1;
try
{
    test.DummyDynamicTest();
    //not dynamic
}
catch (RuntimeBinderException)
{
    //dynamic
}

Однако вы не можете реорганизовать функциональность в другой метод. Это не может быть очень полезно вообще в каких-либо значимых сценариях, игнорировать любой ценой.

Ответ 5

@nawfal К сожалению, ваш метод расширения не работает, когда передается какой-либо нормальный класс poco, который не является динамическим.

Предложение

@Marc Gravell является правильным. Я думаю, что путаница заключается в том, что даже если вы можете заявить что-либо как динамическое. Однако, когда вы создаете экземпляр для конкретного класса, тогда он уже не является действительно динамичным. Вот некоторые тесты, которые я бросил на это. Только test2 и test3 должны пройти. Вы можете протестировать его, пытаясь установить какое-то свойство, которое не существует для каждой динамики. Это вызовет исключение из нединамической динамики.:)

class Program
{
    private class MyDynamic: DynamicObject
    {

    }

    static void Main(string[] args)
    {
        dynamic test1 = new { Name = "Tim" };
        //although I used the dynamic keyword here, it is NOT dynamic. dynamics are only dynamics if they support dynamically adding properties
        //uncommenting this line will cause an exception
        //test.LastName = "Jones"
        if (test1 is IDynamicMetaObjectProvider) { Console.WriteLine("test1"); }

        dynamic test2 = new MyDynamic();
        if (test2 is IDynamicMetaObjectProvider) { Console.WriteLine("test2"); }

        dynamic test3 = new ExpandoObject();
        if (test3 is IDynamicMetaObjectProvider) { Console.WriteLine("test3"); }

        dynamic test4 = new List<string>();
        if (test4 is IDynamicMetaObjectProvider) { Console.WriteLine("test4"); }
    }
}