什么时候应该在c#4.0中使用动态关键字?
什么时候应该在c#4.0中使用动态关键字?……有没有在c#4.0中使用动态关键字的好例子来解释它的用法 只有在不使用Dynamic时才应使用,因为它很痛苦。就像微软办公图书馆一样。在所有其他情况下都应该避免,因为编译类型检查是有益的。下面是使用dynamic的好情况什么时候应该在c#4.0中使用动态关键字?,c#,dynamic,c#-4.0,keyword,C#,Dynamic,C# 4.0,Keyword,什么时候应该在c#4.0中使用动态关键字?……有没有在c#4.0中使用动态关键字的好例子来解释它的用法 只有在不使用Dynamic时才应使用,因为它很痛苦。就像微软办公图书馆一样。在所有其他情况下都应该避免,因为编译类型检查是有益的。下面是使用dynamic的好情况 从Silverlight调用javascript方法 COM互操作 可能在不创建自定义类的情况下读取Xml、Json 这个怎么样?这是我一直在寻找的东西,我想知道为什么没有“动态”很难做到 interface ISomeData {
这个怎么样?这是我一直在寻找的东西,我想知道为什么没有“动态”很难做到
interface ISomeData {}
class SomeActualData : ISomeData {}
class SomeOtherData : ISomeData {}
interface ISomeInterface
{
void DoSomething(ISomeData data);
}
class SomeImplementation : ISomeInterface
{
public void DoSomething(ISomeData data)
{
dynamic specificData = data;
HandleThis( specificData );
}
private void HandleThis(SomeActualData data)
{ /* ... */ }
private void HandleThis(SomeOtherData data)
{ /* ... */ }
}
如果没有采用具体类型的重载方法,则可能需要捕获运行时异常并处理所需的方式
不使用动态
的等效值为:
public void DoSomething(ISomeData data)
{
if(data is SomeActualData)
HandleThis( (SomeActualData) data);
else if(data is SomeOtherData)
HandleThis( (SomeOtherData) data);
...
else
throw new SomeRuntimeException();
}
其中谈到了c#中的动态关键字。要点如下:
dynamic关键字确实很强大,当与动态语言一起使用时,它是不可替代的,但在设计静态类型对象根本无法使用的代码时,它也可以用于棘手的情况
考虑一下缺点:
你可以用
ISomeData specificData = data;
而不是
dynamic specificData = data;
另外,它将确保您不会传递错误类型的数据对象。在所有可以使用动态的情况下使用动态绝对不是一个好主意。这是因为您的程序将失去编译时检查的好处,而且速度也会慢得多。我想复制一篇代码项目文章的摘录,其中定义: 为什么使用动态? 在静态类型的世界中,动态为开发人员提供了很多约束 上吊。处理类型可以为的对象时 在编译时已知,您应该避免使用dynamic关键字 成本。早些时候,我说我最初的反应是否定的,那又怎样 我改变主意了?引用玛格丽特·阿特伍德的话,环境就是一切。什么时候 静态输入,动态输入毫无意义。如果你是 处理未知或动态类型时,通常需要 通过反思与它沟通。反射式代码不容易实现 读取,并具有上述动态类型的所有缺陷。在这个 上下文、动态很有意义。[更多] 而动态关键字的一些特点是:
下面是最近的一个案例,其中使用
动态
是一个简单的解决方案
我已经将一些代码从VB6移植到C#。这些移植的代码仍然需要通过COM互操作调用VB6对象上的其他方法
需要调用的类如下所示:
class A
{
void Foo() {...}
}
class B
{
void Foo() {...}
}
// Obj must be either an A or a B
void Bar(dynamic Obj)
{
Obj.Foo();
}
(也就是说,这就是VB6类在C#中通过COM互操作查看的方式;特别是自动生成的COM可调用包装器)
由于A和B是相互独立的,所以不能将一个强制转换为另一个,并且它们没有公共基类(COM不支持AFAIK和VB6当然不支持的基类。而且它们没有实现公共接口-见下文)
移植的原始VB6代码执行以下操作:
“Obj必须是A或B
子栏(对象为Obj)
调用Obj.Foo()
端接头
现在在VB6中,您可以将对象作为Object
传递,运行时将确定这些对象是否具有方法Foo()
。但在C中,直译是:
// Obj must be either an A or a B
void Bar(object Obj)
{
Obj.Foo();
}
它不会编译,因为对象
没有一个名为“Foo”的方法,而C#是类型安全的将不允许这样做
因此,简单的“修复”是使用动态
,如下所示:
class A
{
void Foo() {...}
}
class B
{
void Foo() {...}
}
// Obj must be either an A or a B
void Bar(dynamic Obj)
{
Obj.Foo();
}
这会将类型安全性推迟到运行时,但假设您已经正确地完成了这项工作,就可以了
对于新的代码,我不赞成这样做,但在这种情况下(从这里的其他答案来看,我认为这并不少见),它是有价值的
考虑的备选方案:
- 使用反射调用Foo()。可能会起作用,但需要更多的努力,可读性较差
- 修改t