什么时候应该在 C# 4.0 中使用动态关键字?

发布于 2024-08-29 08:59:00 字数 71 浏览 2 评论 0原文

什么时候应该在 c# 4.0 中使用动态关键字?......c# 4.0 中任何带有动态关键字的好例子可以解释其用法......

When should one use dynamic keyword in c# 4.0?.......Any good example with dynamic keyword in c# 4.0 that explains its usage....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

天赋异禀 2024-09-05 08:59:00

动态应该仅在当不使用它会很痛苦时使用。就像 MS Office 库一样。在所有其他情况下,应该避免它,因为编译类型检查是有益的。以下是使用动态的良好情况。

  1. 从 Silverlight 调用 javascript 方法。
  2. COM 互操作。
  3. 也许无需创建自定义类即可读取 Xml、Json。

Dynamic should be used only when not using it is painful. Like in MS Office libraries. In all other cases it should be avoided as compile type checking is beneficial. Following are the good situation of using dynamic.

  1. Calling javascript method from Silverlight.
  2. COM interop.
  3. Maybe reading Xml, Json without creating custom classes.
江挽川 2024-09-05 08:59:00

这个怎么样?我一直在寻找的东西,并且想知道为什么没有“动态”就很难做到。

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)
    { /* ... */ }

}

如果您没有采用具体类型的重载方法,您只需要捕获运行时异常并按照您想要的方式处理即可。

不使用dynamic的等效效果是:

    public void DoSomething(ISomeData data)
    {
        if(data is SomeActualData)
          HandleThis( (SomeActualData) data);
        else if(data is SomeOtherData)
          HandleThis( (SomeOtherData) data);
        ...
        else
         throw new SomeRuntimeException();
    }

How about this? Something I've been looking for and was wondering why it was so hard to do without 'dynamic'.

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)
    { /* ... */ }

}

You just have to maybe catch for the Runtime exception and handle how you want if you do not have an overloaded method that takes the concrete type.

Equivalent of not using dynamic will be:

    public void DoSomething(ISomeData data)
    {
        if(data is SomeActualData)
          HandleThis( (SomeActualData) data);
        else if(data is SomeOtherData)
          HandleThis( (SomeOtherData) data);
        ...
        else
         throw new SomeRuntimeException();
    }
迷你仙 2024-09-05 08:59:00

正如此处所述,动态可以使设计不良的外部库更易于使用:Microsoft 提供了 Microsoft 的示例.Office.Interop.Excel 程序集。
通过动态,您可以在使用此程序集时避免许多烦人的显式转换。

另外,与@user2415376相反,这绝对不是处理接口的方法,因为我们从语言诞生之初就已经实现了多态性!
您可以使用

  ISomeData specificData = data;

Plus来代替

dynamic specificData = data;

,它将确保您不会传递错误类型的数据对象。

As described in here dynamics can make poorly-designed external libraries easier to use: Microsoft provides the example of the Microsoft.Office.Interop.Excel assembly.
And With dynamic, you can avoid a lot of annoying, explicit casting when using this assembly.

Also, In opposition to @user2415376 ,It is definitely not a way to handle Interfaces since we already have Polymorphism implemented from the beginning days of the language!
You can use

  ISomeData specificData = data;

instead of

dynamic specificData = data;

Plus it will make sure that you do not pass a wrong type of data object instead.

千笙结 2024-09-05 08:59:00

查看这篇博文,其中讨论了C# 中的动态关键字。要点如下:

dynamic 关键字确实很强大,在与动态语言一起使用时它是不可替代的,但也可以用于设计静态类型对象根本无法完成的代码时的棘手情况。

考虑一下缺点:

  1. 没有编译时类型检查,这意味着除非您对单元测试有 100% 的信心(咳),否则您将面临风险。

  2. 由于额外的运行时开销,动态关键字比旧式静态类型代码使用更多的 CPU 周期,如果性能对您的项目很重要(通常如此),请不要使用动态。

  3. 常见错误包括在公共方法中返回用动态关键字包装的匿名类型。匿名类型特定于程序集,跨程序集返回它们(通过公共方法)将引发错误,即使简单的测试会捕获此错误,您现在有一个只能从特定位置使用的公共方法,这只是糟糕的设计.

  4. 这是一个滑坡,缺乏经验的开发人员渴望编写新的东西并尽力避免更多的类(这不一定限于缺乏经验的人),如果他们在代码中看到动态,他们将开始越来越多地使用动态,通常我会对动态进行代码分析检查/将其添加到代码审查中。

Check this blog post which talks about dynamic keywords in c#. Here is the gist:

The dynamic keyword is powerful indeed, it is irreplaceable when used with dynamic languages but can also be used for tricky situations while designing code where a statically typed object simply will not do.

Consider the drawbacks:

  1. There is no compile-time type checking, this means that unless you have 100% confidence in your unit tests (cough) you are running a risk.

  2. The dynamic keyword uses more CPU cycles than your old fashioned statically typed code due to the additional runtime overhead, if performance is important to your project (it normally is) don’t use dynamic.

  3. Common mistakes include returning anonymous types wrapped in the dynamic keyword in public methods. Anonymous types are specific to an assembly, returning them across assembly (via the public methods) will throw an error, even though simple testing will catch this, you now have a public method which you can use only from specific places and that’s just bad design.

  4. It’s a slippery slope, inexperienced developers itching to write something new and trying their best to avoid more classes (this is not necessarily limited to the inexperienced) will start using dynamic more and more if they see it in code, usually I would do a code analysis check for dynamic / add it in code review.

给我一枪 2024-09-05 08:59:00

这是最近的一个案例,其中使用动态是一个简单的解决方案。这本质上是 COM 互操作场景中的“鸭子打字”。

我已将一些代码从 VB6 移植到 C# 中。此移植代码仍然需要通过 COM 互操作调用 VB6 对象上的其他方法。

需要调用的类如下所示:(

class A
{
    void Foo() {...}
}

class B
{
    void Foo() {...}
}

即,这将是 VB6 类通过 COM 互操作在 C# 中的显示方式。

由于 A 和 B 彼此独立,因此您不能将其中一个强制转换为另一个,并且它们具有没有公共基类(COM 不支持 AFAIK 和 VB6 肯定不支持。而且它们没有实现公共接口 - 参见下面

移植的原始 VB6 代码是这样做的:

' Obj must be either an A or a B 
Sub Bar(Obj As Object) 
    Call Obj.Foo()
End Sub

现在在 VB6 中你可以传递东西。作为 Object ,运行时会判断这些对象是否有方法 Foo() 但在 C# 中,直译是:

// Obj must be either an A or a B 
void Bar(object Obj) 
{
    Obj.Foo();
}

这不会起作用。无法编译,因为 object 没有名为“Foo”的方法,并且 C# 的类型安全不允许这样做,

因此简单的“修复”是使用 dynamic,例如。这:

// Obj must be either an A or a B 
void Bar(dynamic Obj) 
{
    Obj.Foo();
}

这将类型安全性推迟到运行时,但假设您做得正确,

我不会为新代码认可这一点,但在这种情况下(从这里的其他答案来看,我认为这并不罕见)。有价值的。

考虑的替代方案:

  • 使用反射来调用 Foo()。可能会起作用,但是需要更多的努力并且可读性较差。

  • 修改 VB6 库不在此处讨论,但也许可以有一种方法根据 VB6 和 COM 支持的公共接口来定义 A 和 B。但使用动态要容易得多。


注意:这可能只是一个临时解决方案。最终,如果剩余的 VB6 代码被移植,则可以使用正确的类结构。

Here is a recent case in which using dynamic was a straightforward solution. This is essentially 'duck typing' in a COM interop scenario.

I had ported some code from VB6 into C#. This ported code still needed to call other methods on VB6 objects via COM interop.

The classes needing to be called looked like this:

class A
{
    void Foo() {...}
}

class B
{
    void Foo() {...}
}

(i.e., this would be the way the VB6 classes looked in C# via COM interop.

Since A and B are independent of each other you can't cast one to the other, and they have no common base class (COM doesn't support that AFAIK and VB6 certainly didn't. And they did not implement a common interface - see below).

The original VB6 code which was ported did this:

' Obj must be either an A or a B 
Sub Bar(Obj As Object) 
    Call Obj.Foo()
End Sub

Now in VB6 you can pass things around as Object and the runtime will figure out if those objects have method Foo() or not. But in C# a literal translation would be:

// Obj must be either an A or a B 
void Bar(object Obj) 
{
    Obj.Foo();
}

Which will NOT work. It won't compile because object does not have a method called "Foo", and C# being typesafe won't allow this.

So the simple "fix" was to use dynamic, like this:

// Obj must be either an A or a B 
void Bar(dynamic Obj) 
{
    Obj.Foo();
}

This defers type safety until runtime, but assuming you've done it right works just fine.

I wouldn't endorse this for new code, but in this situation (which I think is not uncommon judging from other answers here) it was valuable.

Alternatives considered:

  • Using reflection to call Foo(). Probably would work, but more effort and less readable.

  • Modifying the VB6 library wasn't on the table here, but maybe there could be an approach to define A and B in terms of a common interface, which VB6 and COM would support. But using dynamic was much easier.


Note: This probably will turn out to be a temporary solution. Eventually if the remaining VB6 code is ported over then a proper class structure can be used.

-黛色若梦 2024-09-05 08:59:00

我想复制代码项目帖子的摘录,其中定义:

为什么使用动态?

在静态类型的世界中,动态为开发人员提供了很多帮助
上吊自杀。当处理类型可以是的对象时
在编译时已知,您应该完全避免使用dynamic关键字
成本。之前我说过我最初的反应是否定的,那又怎样呢?
我改变主意了?引用玛格丽特·阿特伍德的话说,背景就是一切。什么时候
静态类型,动态类型没有任何意义。如果你是
处理未知或动态类型时,通常需要
通过反射与之沟通。反射代码并不容易
阅读,并且具有上面动态类型的所有陷阱。在这个
从上下文来看,动态很有意义。[更多]

虽然 Dynamic 关键字的一些特征是:

  1. 动态类型 - 这意味着声明的变量的类型是
    由编译器在运行时决定。
  2. 声明时无需初始化。

例如,

dynamic str; 

str=”I am a string”; //Works fine and compiles

str=2; //Works fine and compiles
  1. 在运行时捕获错误

  2. Intellisense 不可用,因为类型及其相关方法和属性只能在运行时知道。 [https://www.codeproject。 com/Tips/460614/Difference- Between-var-and-dynamic-in-Csharp]

I will like to copy an excerpt from the code project post, which define that :

Why use dynamic?

In the statically typed world, dynamic gives developers a lot of rope
to hang themselves with. When dealing with objects whose types can be
known at compile time, you should avoid the dynamic keyword at all
costs. Earlier, I said that my initial reaction was negative, so what
changed my mind? To quote Margret Attwood, context is all. When
statically typing, dynamic doesn't make a stitch of sense. If you are
dealing with an unknown or dynamic type, it is often necessary to
communicate with it through Reflection. Reflective code is not easy to
read, and has all the pitfalls of the dynamic type above. In this
context, dynamic makes a lot of sense.[More]

While Some of the characteristics of Dynamic keyword are:

  1. Dynamically typed - This means the type of variable declared is
    decided by the compiler at runtime time.
  2. No need to initialize at the time of declaration.

e.g.,

dynamic str; 

str=”I am a string”; //Works fine and compiles

str=2; //Works fine and compiles
  1. Errors are caught at runtime

  2. Intellisense is not available since the type and its related methods and properties can be known at run time only. [https://www.codeproject.com/Tips/460614/Difference-between-var-and-dynamic-in-Csharp]

も让我眼熟你 2024-09-05 08:59:00

在所有可以使用动态的情况下都使用动态绝对是一个坏主意。这是因为您的程序将失去编译时检查的好处,并且速度也会慢得多。

It is definitely a bad idea to use dynamic in all cases where it can be used. This is because your programs will lose the benefits of compile-time checking and they will also be much slower.

旧时模样 2024-09-05 08:59:00

大多数情况下,动态是一种不好的做法,所以我避免使用它,但我发现它在某些情况下非常有用:

1.)您的应用程序在数据库中保存/删除/更新一些内容或从中获取数据。因此,您可能会以 4 种保存/删除/更新/获取数据的方法结束。但不需要 - 在数据库中构造一个简单的存储过程,可以完成所有这些事情(不是那么难),并在代码中执行相同的操作。通过使用动态,您可以从同一方法返回多个结果,例如用于保存/删除/更新的布尔值和用于检索数据的集合(出现错误时+ null)。这节省了我大量的代码行。

2.) 有时我无法避免使用反射,而泛型是不可能或不需要的。所以我改用动态,因为它的性能比反射更好。

Mostly dynamic is a bad practice to use so I avoid It, but I find It very useful in some scenarios:

1.) Your application saves/deletes/updates some stuff in database or gets data from It. So you'll probably end with 4 methods for save/delete/update/get data. But not needed - construct a simple stored procedure in database that can do all those things (not so hard), and do same in your code. By using dynamic you can return multiple results from same method, like bool for save/delete/update and collection for retrieving data (+ null when error appears). That saves me tons of code lines.

2.) Sometimes I cant' avoid using reflection and generics aren't possible or not needed. So I use dynamic instead, because of It's better performance than reflection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文