v
除非变量为,否则以下代码将始终返回 true null
:
v is dynamic
并且以下测试将无法编译(“typeof 运算符不能用于动态类型”):
v.GetType() == typeof(dynamic)
那么有没有办法测试变量是否为dynamic
?
首先,您需要将变量和对象分开。如果定义为 ,则dynamic
变量是动态的。就这些。没有什么了。字段或属性将使用属性进行注释,[Dynamic]
即
public dynamic Foo {get;set;}
实际上是:
[Dynamic]
public object Foo {get;set;}
这基本上作为编译器通过dynamic
API 而不是通过 OOP API 访问对象的提示。
一个对象dynamic
如果实现了它就支持全部功能IDynamicMetaObjectProvider
- 但是,这样的对象可以通过dynamic
API 和常规 OOP API 访问(它可以同时具有两者)。同样,可以通过任一 API 访问未实现的对象IDynamicMetaObjectProvider
(但是:只有公共成员可以通过 访问dynamic
)。
没有 CLR 类型称为dynamic
. C# 编译器生成所有dynamic
类型的值,object
然后调用自定义绑定代码来确定如何处理它们。如果dynamic
使用,它将显示为Object
.
但是您可以检查实例是否属于类型IDynamicMetaObjectProvider
,或者您可以检查类型是否实现IDynamicMetaObjectProvider
在 C# 中,动态意味着没有编译时检查,它将具有 = 符号另一侧的类型。然而 GetType 是一个运行时评估,所以你总是要检索声明的类型而不是动态的。
您可以在这里阅读更多内容:http: //msdn.microsoft.com/en-us/magazine/gg598922.aspx
正如其他人所说,总会有一个运行时类型。
依赖于动态变量不支持扩展方法这一事实,可以检测局部变量。
static void DummyDynamicTest<T>(this T t) //extension method
{
}
dynamic test = 1;
try
{
test.DummyDynamicTest();
//not dynamic
}
catch (RuntimeBinderException)
{
//dynamic
}
但是,您不能将功能重构为另一种方法。这在任何有意义的场景中都不是很有用,不惜一切代价忽略。
@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"); }
}
}