有没有办法测试变量是否是动态的?

除非变量vnull否则以下代码将始终返回true:

 v is dynamic 

并且以下测试将无法编译(“typeof运算符不能用于动态类型”):

 v.GetType() == typeof(dynamic) 

那么有没有办法测试变量是否是dynamic

首先,您需要将变量和对象分开。 如果变量定义为dynamic变量,则该变量是dynamic 。 就这些。 没有更多。 字段属性将使用[Dynamic]属性进行注释,即

 public dynamic Foo {get;set;} 

实际上是:

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

这基本上作为编译器通过dynamic API而不是通过OOP API访问对象的提示。

如果一个对象实现了IDynamicMetaObjectProvider ,它就支持完整的dynamicfunction – 但是,这样的对象可以通过dynamic API和常规OOP API(它可以同时具有)来访问。 同样,可以通过任一API访问未实现IDynamicMetaObjectProvider的对象(但是:只有公共成员才能通过dynamic )。

没有称为dynamic CLR类型。 C#编译器生成类型为object所有dynamic值,然后调用自定义绑定代码以确定如何处理它们。 如果使用dynamic ,它将显示为Object

但您可以检查实例是否为IDynamicMetaObjectProvider类型,或者您可以检查该类型是否实现IDynamicMetaObjectProvider

在C#中,动态意味着没有complile-time检查,它将具有=符号的另一侧的类型。 但是GetType是运行时评估,因此您总是要检索声明的类型而不是动态。

你可以在这里阅读更多内容: http : //msdn.microsoft.com/en-us/magazine/gg598922.aspx

总有一种运行时类型,正如其他人所说的那样。

有一个hack来检测局部变量,依赖于动态变量不支持扩展方法的事实。

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

但是,您无法将该function重构为另一种方法。 在任何有意义的场景中,这都不是非常有用,不惜任何代价忽略。

@nawfal遗憾的是,当传入任何非动态的普通poco类时,你的扩展方法会失败。

@Marc Gravell提出的解决方案是正确的。 我认为混淆在于即使你可以宣布任何动态的事实。 但是,当您将其实例化为具体类时,它不再是真正动态的。 以下是我投入的一些测试。 只有test2和test3才能通过。 您可以通过尝试设置每个动态上存在的属性来进一步测试它。 这将导致非动态动态exception。 🙂

 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(); if (test4 is IDynamicMetaObjectProvider) { Console.WriteLine("test4"); } } }