Is there a way to test if a variable is dynamic?

前端 未结 5 1663
北荒
北荒 2020-12-18 18:26

The following piece of code will always return true unless the variable v is null:

v is dynamic

and the following

相关标签:
5条回答
  • 2020-12-18 19:06

    In C# dynamic means no complile-time check and it's gonna have the type of the other side of the = symbol. However GetType is a runtime evaluation, so you always gonna retrieve declared type and not dynamic.

    You can read a little bit more here: http://msdn.microsoft.com/en-us/magazine/gg598922.aspx

    0 讨论(0)
  • 2020-12-18 19:23

    There will always be a run-time type as others have said.

    There is a hack to detect for local variables, relying on the fact that dynamic variables doesn't support extension methods.

    static void DummyDynamicTest<T>(this T t) //extension method
    {
    
    }
    
    dynamic test = 1;
    try
    {
        test.DummyDynamicTest();
        //not dynamic
    }
    catch (RuntimeBinderException)
    {
        //dynamic
    }
    

    However you can't refactor the functionality into another method. This can't be very useful at all in any meaningful scenarios, ignore at any cost.

    0 讨论(0)
  • 2020-12-18 19:25

    Firstly, you need to separate the variable and the object. A variable is dynamic if it is defined as dynamic. That is all. There is nothing more. A field or property would be annotated with the [Dynamic] attribute, i.e.

    public dynamic Foo {get;set;}
    

    is actually:

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

    This basically acts as a prompt for the compiler to access the object via the dynamic API rather than via the OOP API.

    An object supports full dynamic capabilities if it implements IDynamicMetaObjectProvider - however, such an object can be accessed via both the dynamic API and via the regular OOP API (it can have both). Equally, an object that doesn't implement IDynamicMetaObjectProvider can be accessed via either API (but: only the public members will be available via dynamic).

    0 讨论(0)
  • 2020-12-18 19:25

    There is no CLR type called dynamic. The C# compiler makes all dynamic values of type object and then calls custom binding code to figure out how to handle them. If dynamic was used, it will show up as Object.

    But You can check if an instance is of type IDynamicMetaObjectProvider or you can check whether the type implements IDynamicMetaObjectProvider

    0 讨论(0)
  • 2020-12-18 19:27

    @nawfal Sadly your extension method fails when any normal poco class that is not dynamic is passed in.

    @Marc Gravell's proposed solution is correct. I think the confusion lies around the fact that even though you can declare anything as dynamic. However, when you instantiate it to a concrete class then it is no longer truly dynamic. Here are some tests I threw at it. Only test2 and test3 should pass. You can further test it out by trying to set some property that does not exist on each dynamic. Which will cause an exception on the non dynamic dynamics. :)

    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"); }
        }
    }
    
    0 讨论(0)
提交回复
热议问题