C#中的Dynamic相关的知识点
在C#中,dynamic
关键字允许我们延迟对对象类型的解析。这意味着我们可以声明一个变量为 dynamic
类型,而不需要知道它的确切类型。在编译时,编译器不会检查 dynamic
变量的类型,而是将类型检查推迟到运行时。这使得 dynamic
变量可以用于处理不同类型的对象,只要这些对象在运行时支持相应的操作。
说人话就是: 写代码的时候时候编辑器不报错、不报警告. 运行的时候, 如果有错会报错.由于类型检查放到了运行时候,因此理论上来说速度会慢点.
1.微软官方对dynamic的讲解和示例:
Using type dynamic - C# | Microsoft Learn
点击超链接或者点击下面的连接可以访问微软官方讲解dynamic的内容
https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/interop/using-type-dynamic
csharp
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
// The following call to exampleMethod1 causes a compiler error
// if exampleMethod1 has only one parameter. Uncomment the line
// to see the error.
//ec.exampleMethod1(10, 4);
dynamic dynamic_ec = new ExampleClass();
// The following line is not identified as an error by the
// compiler, but it causes a run-time exception.
dynamic_ec.exampleMethod1(10, 4);
// The following calls also do not cause compiler errors, whether
// appropriate methods exist or not.
dynamic_ec.someMethod("some argument", 7, null);
dynamic_ec.nonexistentMethod();
}
csharp
class ExampleClass
{
public ExampleClass() { }
public ExampleClass(int v) { }
public void exampleMethod1(int i) { }
public void exampleMethod2(string str) { }
}
2.dynamic的简介
dynamic
关键字的作用和简介如下:
-
延迟类型检查 :使用
dynamic
关键字,我们可以延迟类型检查直到运行时
。这允许我们在编译时避免类型不匹配的错误,因为这些错误会在运行时被捕获。 -
动态类型赋值 :我们可以将任何类型的对象赋值给
dynamic
类型的变量。例如,我们可以这样做:csharpdynamic myDynamicVar = "Hello, World!"; // 可以看出dynamic是一种类型 myDynamicVar = 42; myDynamicVar = true;
-
动态方法调用 :
dynamic
变量可以调用任何方法,即使这些方法在编译时不存在于对象的类型中。在运行时,如果对象支持这些方法,它们将被调用;否则,将抛出异常。 -
动态属性访问 :与动态方法调用类似,
dynamic
变量可以访问任何属性,即使这些属性在编译时不存在于对象的类型中。 -
动态事件处理 :
dynamic
变量可以订阅和引发事件,即使这些事件在编译时不存在于对象的类型中。 -
动态运算符重载 :
dynamic
变量可以参与任何运算符重载操作,即使这些运算符在编译时不存在于对象的类型中。 -
与
object
的区别 :虽然dynamic
和object
都可以表示任何类型的对象,但它们在处理方式上有所不同。object
类型在编译时进行类型检查,而dynamic
类型在运行时进行类型检查。 -
使用场景 :
dynamic
关键字通常用于处理动态类型语言(如 JavaScript)与C#之间的交互,以及处理 COM 对象和动态生成对象的情况。 -
性能考虑 :由于
dynamic
关键字在运行时进行类型检查,因此它可能会影响性能。在性能敏感的应用中,应谨慎使用dynamic
。 -
异常处理 :当尝试对
dynamic
变量执行不支持的操作时,将抛出RuntimeBinderException
异常。总之,
dynamic
关键字提供了一种灵活的方式来处理不同类型的对象,但它也带来了一些性能和异常处理的挑战。在使用dynamic
时,应权衡其优点和缺点,并根据具体场景做出决策。
3.Dynamic和Var的区别:
在c#中我们使用var来进行自动类型推导, 在C++中使用的是auto来自动类型推导. 在C#中dynamic和var的区别是: var不是类型, dynamic是类型. 即
可以使用 dynamic 来声明变量, 使用var不可以声明变量
csharp
using System;
namespace Dynamic
{
class DynamicAndVar
{
static void Main(string[] args)
{
dynamic ab = 999; // 可以的
var c = 0; // 不可以的, 编译器报错
Console.WriteLine(ab); // 可以输出结果999
Console.ReadKey();
}
}
}
4.使用dynamic
那么什么时候该使用,什么时候该避免滥用.
何时使用 dynamic
:
- 与动态语言交互 :当需要与JavaScript、Python等动态类型语言交互时,
dynamic
可以提供便利。例如,在ASP.NET MVC中使用JavaScript对象时,可以使用dynamic
来避免复杂的类型转换。 - 处理COM对象 :在与COM交互时,
dynamic
类型允许您以更自然的方式处理COM接口和对象,因为COM对象通常是在运行时动态解析的。COM对象(Component Object Model object)是指遵循COM(组件对象模型)规范的对象。COM是微软开发的一种二进制接口
标准,用于实现不同编程语言和平台之间的组件交互。COM对象可以在不同的应用程序、进程和机器之间进行通信和交互。 - 动态生成的类型 :当处理由反射、代码生成或第三方库动态创建的对象时,
dynamic
可以简化代码。 - 原型开发和快速迭代 :在原型开发和快速迭代阶段,
dynamic
可以帮助您更快地实现功能,而无需担心类型定义。
避免滥用 dynamic
:
-
性能考虑 :
dynamic
类型在运行时进行类型检查,这可能会影响性能。在性能敏感的应用中,应避免使用dynamic
。 -
类型安全性 :
dynamic
类型牺牲了编译时的类型检查,这可能导致运行时错误。在需要严格类型安全性的场景中,应避免使用dynamic
。 -
代码可维护性 :使用
dynamic
可能使代码更难以理解和维护,因为编译器无法提供类型相关的错误检查。这可能导致在代码审查和调试时花费更多时间。 -
异常处理 :
dynamic
类型在运行时抛出RuntimeBinderException
异常,这使得异常处理变得复杂。在需要明确异常处理策略的场景中,应避免使用dynamic
。 -
设计模式 :在设计模式中,如依赖注入、工厂模式等,通常不推荐使用
dynamic
,因为这些模式依赖于明确的类型定义和接口。 -
避免过度使用 :即使在适当的情况下使用
dynamic
,也应避免过度使用。应仅在其真正带来好处的情况下使用,而不是作为一种通用的编程习惯。