一起谈.NET技术,了解 C# 4 中的 Dynamic 关键字

简介:   dynamic 关键字和动态语言运行时 (DLR) 是 C# 4 和 Microsoft .NET Framework 4 中的重大新增功能。 这些功能在宣布时就引起了人们的极大兴趣,并伴随着许多疑问。

  dynamic 关键字和动态语言运行时 (DLR) 是 C# 4 和 Microsoft .NET Framework 4 中的重大新增功能。 这些功能在宣布时就引起了人们的极大兴趣,并伴随着许多疑问。 同时人们也给出了很多答案,但这些答案现在已散布于各种文档以及各种技术博客和文章之中。 这样,人们在各种论坛和会议上总是一遍又一遍地提出相同的问题。

  本文全面概述了 C# 4 中新增的动态功能,并且深入探讨了这些功能如何同其他语言和框架功能(例如反射或隐式类型化变量)一起使用。 鉴于已有大量信息可用,我有时会重新使用一些经典示例,并提供指向原始源的链接。 我还将提供指向相关内容的大量链接,供您进一步阅读。

  什么是“动态”?

  编程语言有时可划分为静态类型化语言和动态类型化语言。 C# 和 Java 经常被认为是静态类型化语言的例子,而 Python、Ruby 和 JavaScript 是动态类型化语言的例子。

  一般而言,动态语言不执行编译时类型检查,仅在运行时识别对象的类型。 这种方法有利有弊:代码编写起来往往更快、更容易,但同时,由于您不会获得编译器错误,只能通过单元测试和其他方法来确保应用程序正常运行。

  C# 最初是作为纯静态语言创建的,但 C# 4 添加了一些动态元素,用以改进与动态语言和框架之间的互操作性。 C# 团队考虑了多种设计选项,但最终确定添加一个新关键字来支持这些功能:dynamic。

  dynamic 关键字可充当 C# 类型系统中的静态类型声明。 这样,C# 就获得了动态功能,同时仍然作为静态类型化语言而存在。 若要了解为何以及如何做出了这样的决定,请参考 PDC09 (microsoftpdc.com/2009/FT31) 上由Mads Torgersen 撰写的演示文稿“C# 4 中的动态绑定”。 尤其是,动态对象被认定是 C# 语言中的“一等公民”,因此没有用于打开或关闭动态功能的选项,并且没有向 C# 添加过类似于 Visual Basic 中的 Option Strict On/Off 之类的功能。

  当您使用 dynamic 关键字时,您就告诉编译器关闭编译时检查。 网上以及 MSDN 文档中 (msdn.microsoft.com/library/dd264736) 有大量关于如何使用该关键字的示例。 下面是一个常见示例:

 
 
dynamic d = " test " ;
Console.WriteLine(d.GetType());
// Prints "System.String".
d = 100 ;
Console.WriteLine(d.GetType());
// Prints "System.Int32".     

  如您所见,可以将不同类型的对象分配给已声明为 dynamic 的变量。 这段代码会通过编译,并在运行时确定对象的类型。 不过,下面的代码也会通过编译,但在运行时会引发异常:

 
 
dynamic d = " test " ;
// The following line throws an exception at run time.
d ++ ;   

  原因是相同的:编译器不知道该对象的运行时类型,因此无法告诉您递增操作在此情况下不受支持。

  缺少编译时类型检查也会导致 IntelliSense 功能无效。 由于 C# 编译器不知道对象的类型,因此它无法枚举该对象的属性和方法。 正如在用于 Visual Studio 的 IronPython 工具中那样,通过附加的类型推断可能会解决此问题,但目前 C# 不提供这种类型推断。

  但是,在许多可能获益于动态功能的方案中,由于代码使用了字符串文本而导致 IntelliSense 还是不可用。 本文在后面将对这一问题进行更详细的讨论。

  Dynamic、Object 还是 Var?

  那么,dynamic、object 和 var 之间的实际区别是什么?何时应使用它们? 下面是每个关键字的简短定义和一些示例。

  关键字 object 表示 System.Object 类型,它是 C# 类层次结构中的根类型。 此关键字经常在编译时无法确定对象类型时使用,而这种情况经常在各种互操作性情形中发生。

  您需要使用显式转换将已声明为 object 的变量转换为特定类型:

 
 
object objExample = 10 ;
Console.WriteLine(objExample.GetType());
      

  显然,这将输出 System.Int32。 但是,因为静态类型为 System.Object,所以您在这里需要一个显式转换:

 
 
objExample = ( int )objExample + 10 ;       

  您可以赋予不同类型的值,因为它们都是从 System.Object 继承的:

 
 
objExample = " test "         

  从 C# 3.0 起,关键字 var 开始用于隐式类型化局部变量以及匿名类型。 此关键字经常与 LINQ 结合使用。 当使用 var 关键字声明变量时,将在编译时根据初始化字符串推断该变量的类型。 在运行时无法更改该变量的类型。 如果编译器不能推断类型,它会生成一个编译错误:

 
 
var varExample = 10 ;
Console.WriteLine(varExample.GetType());
  

  这段代码会输出 System.Int32,与静态类型相同。

  在下面的示例中,因为 varExample 的静态类型为 System.Int32,所以不需要转换:

 
 
varExample = varExample + 10 ;   

  下面一行不进行编译,因为只能将整数赋给 varExample:

 
 
varExample = " test " ;   

  C# 4 中引入的 dynamic 关键字可使某些传统上依赖于 object 关键字的情形更容易编写和维护。 实际上,动态类型在后台使用 System.Object 类型。但与 object 不同的是,动态类型不需要在编译时执行显式转换操作,因为它仅在运行时识别类型:

 
 
dynamic dynamicExample = 10 ;
Console.WriteLine(dynamicExample.GetType());
    

  此段代码会输出 System.Int32。

  在下面这一行中不需要转换,因为仅在运行时识别类型:

 
 
dynamicExample = dynamicExample + 10 ;  

  可以将不同类型的值赋给 dynamicExample:

 
 
dynamicExample = " test " ;

在 C# 常见问题解答博客 (bit.ly/c95hpl) 上,提供了关于关键字 object 和 dynamic 之间差别的详细博客文章。

  有时会引起混淆的是,所有这些关键字可以一起使用,即它们不是互相排斥的。 例如,我们来看一看下面的代码:

 
 
dynamic dynamicObject = new Object();
var anotherObject
= dynamicObject;  

  anotherObject 的类型是什么? 我的回答是:dynamic。 请记住,在 C# 类型系统中,dynamic 实际上是一个静态类型,因此,编译器将为 anotherObject 推断此类型。 务必要知道,var 关键字不过是一个指令,它让编译器根据变量的初始化表达式推断类型;var 不是类型。

  动态语言运行时

  说起 C# 语言环境中的“dynamic”这一术语,它通常指下面两个概念之一:C# 4 中的 dynamic 关键字或 DLR。 虽然这两个概念是相关的,但也务必要了解它们之间的差别。

  DLR 有两个主要目的。 首先,它实现动态语言和 .NET Framework 之间的互操作。 其次,它将动态行为引入 C# 和 Visual Basic 之中。

  DLR 的创建吸取了构建 IronPython (ironpython.net) 时的经验教训(IronPython 是在 .NET Framework 上实现的第一种动态语言)。 在构建 IronPython 时,工作团队发现他们可以针对多种语言重复使用他们的实现,因此,他们为 .NET 动态语言创建了一个公共基础平台。 与 IronPython 一样,DLR 已成为一个开源项目,其源代码目前在 dlr.codeplex.com 上提供。

  后来,.NET Framework 4 中也纳入了 DLR,以支持 C# 和 Visual Basic 中的动态功能。 如果您只需要 C# 4 中的 dynamic 关键字,那么使用 .NET Framework 就可以了。在大多数情况下,仅凭 .NET Framework 即可处理与 DLR 之间的所有交互。 但是,如果您希望实现新的动态语言或将其迁移到 .NET,则可以获益于开源项目中额外的帮助程序类,该开源项目为语言实现人员提供了更多功能和服务。

  在静态类型化语言中使用 Dynamic

  我们并不期待每个人都尽可能使用动态而不是静态类型声明。 编译时检查是一个强大的工具,对它的使用多多益善。 而且,再次指出,C# 中的动态对象不支持 IntelliSense,这对总体工作效率可能会有些影响。

  同时,在出现 dynamic 关键字和 DLR 之前,有一些方案在 C# 中曾经难以实现。 在以前的大多数情况下,开发人员使用 System.Object 类型和显式转换,同样不能很好地利用编译时检查和 IntelliSense。 下面是一些例子。

  人们最熟知的一个情况是,有时必须使用 object 关键字来实现与其他语言或框架的互操作性。 通常,您必须依靠反射来获取对象的类型以及访问其属性和方法。 语法有时难以阅读,因此代码难以维护。 此时使用动态功能可能比使用反射更加容易和方便。

  Anders Hejlsberg 在 PDC08 (channel9.msdn.com/pdc2008/TL16) 上提供了一个极好的例子,如下所示:

 
 
object calc = GetCalculator();
Type calcType
= calc.GetType();
object res = calcType.InvokeMember(
" Add " , BindingFlags.InvokeMethod,
null , new object [] { 10 , 20 });
int sum = Convert.ToInt32(res);

  该函数返回一个计算器,但系统在编译时不知道此计算器对象的精确类型。 代码所依赖的唯一事情是此对象应具有 Add 方法。 请注意,此方法无法使用 IntelliSense,因为您以字符串文本的形式提供了方法名称。

  使用 dynamic 关键字,代码就很简单了:

 
 
dynamic calc = GetCalculator();
int sum = calc.Add( 10 , 20 );

假设情况没有变化:存在某种我们希望其具有 Add 方法的未知类型的对象。 与上一个示例一样,此方法也不能使用 IntelliSense。 但语法阅读和使用起来要容易很多,看上去就像在调用一个普通的 .NET 方法。

  动态方法包

  可以利用动态功能的另外一个例子是创建动态方法包,动态方法包就是可在运行时添加和删除属性及方法的对象。

  .NET Framework 4 有一个新的命名空间:System.Dynamic。 此命名空间实际上是 DLR 的一部分。 System.Dynamic.ExpandoObject 和 System.Expando.DynamicObject 类与新的 dynamic 关键字相结合,有助于以清晰和易于阅读的方式来创建动态结构和层次结构。

  例如,下面说明了如何使用 ExpandoObject 类来添加属性和方法:

 
 
dynamic expando = new ExpandoObject();
expando.SampleProperty
= " This property was added at run time " ;
expando.SampleMethod
= (Action)(() => Console.WriteLine(expando.SampleProperty));
expando.SampleMethod();

  要了解更加深入的方案,您一定要看看关于 ExpandoObject 和 DynamicObject 类的 MSDN 文档。 同时,还有一些值得一看的文章,比如由 Bill Wagner 撰写的文章“动态方法包”(msdn.microsoft.com/library/ee658247) 以及 C# 常见问题解答博客文章“C# 4.0 中的 Dynamic:ExpandoObject 简介”(bit.ly/amRYRw)。

  类包装

  您可以为自己的库提供更好的语法,或为现有库创建包装。 与前两个方案相比,这是一个更高级的方案,并且需要对 DLR 具体内容有更深入的了解。

  对于简单情况,可以使用 DynamicObject 类。 在这个类中,可以将方法和属性的静态声明与动态调度进行混合。 这样,您就可以在一个类属性中存储一个要为其提供更佳语法的对象,但通过动态调度来处理针对该对象的所有操作。

  例如,请看一下图 1 中的 DynamicString 类,该类包装了一个字符串,并在通过反射实际调用所有方法之前显示这些方法的名称。

 
 
public class DynamicString : DynamicObject {
string str;

public DynamicString( string str) {
this .str = str;
}

public override bool TryInvokeMember(
InvokeMemberBinder binder,
object [] args,
out object result) {
Console.WriteLine(
" Calling method: {0} " , binder.Name);
try {
result
= typeof ( string ).InvokeMember(
binder.Name,
BindingFlags.InvokeMethod
|
BindingFlags.Public
|
BindingFlags.Instance,
null , str, args);
return true ;
}
catch {
result
= null ;
return false ;
}
}
}
 

  若要实例化该类,应使用 dynamic 关键字:

 
 
dynamic dStr = new DynamicString( " Test " );
Console.WriteLine(dStr.ToUpper());
Console.ReadLine();
   

  当然,这个特定示例出于演示目的而设计,不具有实际效率。 但是,如果您拥有已严重依赖于反射的 API,就可以如此处所示将所有通过反射进行的调用打包,以便针对 API 的最终用户隐藏这些调用。

  有关更多示例,请参见 MSDN 文档 (msdn.microsoft.com/library/system.dynamic.dynamicobject) 以及 C# 常见问题解答博客文章“C# 4.0 中的 Dynamic:通过 DynamicObject 创建包装”(bit.ly/dgS3od)。

  如前所述,DynamicObject 类是由 DLR 提供的。 生成动态对象所需要的仅仅是 DynamicObject 或 ExpandoObject。 但是,某些动态对象具有用于访问成员和调用方法的复杂绑定逻辑。 这种对象需要实现 IDynamicMetaObjectProvider 接口并提供其自己的动态调度。 这是一种高级方案,感兴趣的读者可以读一下由 Bill Wagner 撰写的文章“实现动态接口”(msdn.microsoft.com/vcsharp/ff800651),以及由 Alex Turner 及 Bill Chiles 撰写的文章“库创作者 DLR 入门”(dlr.codeplex.com)。

  可编写脚本的应用程序

  脚本是向应用程序提供可扩展性的一种强大方法。 Microsoft Office 可作为这方面的一个好例子:由于 Visual Basic for Applications (VBA) 的存在,可以使用大量的宏、加载项和插件。 现在,DLR 提供了一组公用的语言宿主 API,因此可让您创建可编写脚本的应用程序。

  例如,您可以创建一个应用程序,使用户能够自己在其中添加功能而不需要主产品提供新功能,例如向游戏中添加新的字符和映射,或向业务应用程序添加新的图表。

  您必须使用来自 dlr.codeplex.com 的开源版 DLR 而不是由 .NET Framework 4 使用的 DLR,因为 DLR 脚本编写和宿主 API 现在仅在开源版中提供。 另外,假定的情况是您不是使用 C# 编写脚本,而是使用一种 .NET 动态语言(如 IronPython 或 IronRuby)来编写。 然而,实际上任何语言都可以支持这些 API,包括不是在 DLR 之上实现的语言。

  有关使用此功能的详细信息,请观看 PDC09 (microsoftpdc.com/2009/FT30) 上由 Dino Viehland 所做的演示“使用动态语言生成可编写脚本的应用程序”。

  识别动态对象

  如何区分动态对象与其他对象? 一个简便方法是使用内置的 IDE 功能。 您可以将鼠标光标悬停在对象上以查看其声明类型,或检查 IntelliSense 是否可用。

  然而在运行时,情况会变得更加复杂。 您无法检查变量是否是通过 dynamic 关键字声明的 — 动态对象的运行时类型是它所存储的值的类型,您无法获取其静态类型声明。 这种情况与将变量声明为 object 时的情况相同:在运行时,您只能获取变量所存储的值的类型;无法判断此变量最初是否声明为 object。

  运行时所能确定的是对象是否来自 DLR。 知道这种情况可能十分重要,因为像 ExpandoObject 和 DynamicObject 类型的对象可在运行时改变其行为,例如,添加和删除属性及方法。

  此外,也无法使用标准反射方法来获取有关这些对象的信息。 如果向 ExpandoObject 类的实例添加属性,则无法通过反射获取该属性:

 
 
dynamic expando = new ExpandoObject();
expando.SampleProperty
= " This property was added at run time " ;
PropertyInfo dynamicProperty
= expando.GetType().GetProperty( " SampleProperty " );
// dynamicProperty is null.

  有利的方面是,在 .NET Framework 4 中,所有可动态添加和删除成员的对象都必须实现一个特定接口:System.Dynamic.IDynamicMetaObjectProvider。 DynamicObject 和 ExpandoObject 类也实现了这个接口。 不过,这并不表示任何使用 dynamic 关键字声明的对象都实现此接口:

 
 
dynamic expando = new ExpandoObject();
Console.WriteLine(expando
is IDynamicMetaObjectProvider);
// True
dynamic test = " test " ;
Console.WriteLine(test
is IDynamicMetaObjectProvider);
// False

因此,如果将动态功能与反射一起使用,则请记住,反射不适用于动态添加的属性和方法,并且最好检查正在反射的对象是否实现了 IDynamicMetaObjectProvider 接口。

  动态功能与 COM 互操作

  C# 团队在 C# 4 版本中专门考虑的 COM 互操作方案是针对 Microsoft Office 应用程序(如 Word 和 Excel)进行编程。 他们的目的是让这一任务在 C# 中变得像在 Visual Basic 中那样容易和自然。 这也是 Visual Basic 和 C# 共同发展策略的一部分,这个策略旨在实现两种语言的功能对等,并相互借鉴最佳、最具效率的解决方案。

  若需了解详细信息,请参阅 Scott Wiltamuth 的 Visual Studio 博客文章“C# 和 VB 共同发展”(bit.ly/bFUpxG)。

  显示了一段 C# 4 代码,该代码向 Excel 工作表的第一个单元格中添加一个值,然后向第一列应用 AutoFit 方法。 每行下面的注释显示了 C# 3.0 及更早版本的中的等效代码。

 
 
// Add this line to the beginning of the file:
// using Excel = Microsoft.Office.Interop.Excel;

var excelApp
= new Excel.Application();

excelApp.Workbooks.Add();
// excelApp.Workbooks.Add(Type.Missing);

excelApp.Visible
= true ;

Excel.Range targetRange
= excelApp.Range[ " A1 " ];
// Excel.Range targetRange = excelApp.get_Range("A1", Type.Missing);

targetRange.Value
= " Name " ;
// targetRange.set_Value(Type.Missing, "Name");

targetRange.Columns[
1 ].AutoFit();
// ((Excel.Range)targetRange.Columns[1, Type.Missing]).AutoFit();

  此示例有趣的地方是,您在代码中的任何位置都看不到 dynamic 关键字。实际上,该关键字仅在下面一行中用到:

 
 
targetRange.Columns[ 1 ].AutoFit();
// ((Excel.Range)targetRange.Columns[1, Type.Missing]).AutoFit();

  在 C# 3.0 版中,targetRange.Columns[1, Type.Missing] 返回 object,这便是需要向 Excel.Range 转换的原因。 但在 C# 4 和 Visual Studio 2010 中,这样的调用将以静默方式转换为动态调用。 因此,C# 4 中 targetRange.Columns[1] 的类型实际上是 dynamic。

  另一个突出特点是,C# 4 中的 COM 互操作改进不仅限于 dynamic。 由于其他一些新增功能(例如索引属性以及命名参数和可选参数),其他所有行中的代码也有所改进。 由 Chris Burrows 撰写的 MSDN 杂志 文章“.NET Framework 4 中的新增 C# 功能”(msdn.microsoft.com/magazine/ff796223) 中对这些新增功能做了很好的概述。

  从哪里可以获取更多信息?

  希望本文已涵盖您对 C# 4 中的 dynamic 关键字可能有的大部分疑问,但我确信本文并非面面俱到。 如果您有意见、问题或建议,敬请光临 dlr.codeplex.com/discussions 提出。 其他人可能已经提过您关心的问题,或者您可以发起新的讨论。 我们拥有一个活跃的社区,欢迎新成员加入。

目录
相关文章
|
13天前
|
人工智能 开发框架 量子技术
【专栏】.NET 技术:驱动创新的力量
【4月更文挑战第29天】.NET技术,作为微软的开发框架,以其跨平台、开源和语言多样性驱动软件创新。它在云计算、AI/ML、混合现实等领域发挥关键作用,通过Azure、ML.NET等工具促进新兴技术发展。未来,.NET将涉足量子计算、微服务和无服务器计算,持续拓宽软件开发边界,成为创新的重要推动力。掌握.NET技术,对于开发者而言,意味着握有开启创新的钥匙。
|
13天前
|
开发框架 .NET C#
【专栏】理解.NET 技术,提升开发水平
【4月更文挑战第29天】本文介绍了.NET技术的核心概念和应用,包括其跨平台能力、性能优化、现代编程语言支持及Web开发等特性。文章强调了深入学习.NET技术、关注社区动态、实践经验及学习现代编程理念对提升开发水平的重要性。通过这些,开发者能更好地利用.NET构建高效、可维护的多平台应用。
|
13天前
|
机器学习/深度学习 vr&ar 开发者
【专栏】.NET 技术:引领开发新方向
【4月更文挑战第29天】本文探讨了.NET技术如何引领软件开发新方向,主要体现在三方面:1) 作为跨平台开发的先锋,.NET Core支持多操作系统和移动设备,借助.NET MAUI创建统一UI,适应物联网需求;2) 提升性能和开发者生产力,采用先进技术和优化策略,同时更新C#语言特性,提高代码效率和可维护性;3) 支持现代化应用架构,包括微服务、容器化,集成Kubernetes和ASP.NET Core,保障安全性。此外,.NET还不断探索AI、ML和AR/VR技术,为软件开发带来更多创新可能。
|
13天前
|
开发框架 Cloud Native 开发者
【专栏】剖析.NET 技术的核心竞争力
【4月更文挑战第29天】本文探讨了.NET框架在软件开发中的核心竞争力:1) .NET Core实现跨平台与云原生技术的融合,支持多操作系统和容器化;2) 提升性能和开发者生产力,采用JIT、AOT优化,提供C#新特性和Roslyn编译器平台;3) 支持现代化应用架构,包括微服务和容器化,内置安全机制;4) 丰富的生态系统和社区支持,拥有庞大的开发者社区和微软的持续投入。这些优势使.NET在竞争激烈的市场中保持领先地位。
|
13天前
|
开发框架 .NET 开发者
【专栏】领略.NET 技术的创新力量
【4月更文挑战第29天】.NET技术自ASP.NET起历经创新,现以.NET Core为核心,展现跨平台能力,提升性能与生产力,支持现代化应用架构。.NET Core使开发者能用同一代码库在不同操作系统上构建应用,扩展至移动和物联网领域。性能提升,C#新特性简化编程,Roslyn编译器优化代码。拥抱微服务、容器化,内置安全机制,支持OAuth等标准。未来.NET 6将引入更快性能、Hot Reload等功能,预示着.NET将持续引领软件开发潮流,为开发者创造更多机会。
|
13天前
|
物联网 vr&ar 开发者
【专栏】.NET 技术:为开发注入活力
【4月更文挑战第29天】本文探讨了.NET技术的创新,主要体现在三个方面:1) .NET Core实现跨平台开发革命,支持多种操作系统和硬件,如.NET MAUI用于多平台UI;2) 性能提升与生产力飞跃,C#新特性简化编程,JIT和AOT优化提升性能,Roslyn提供代码分析工具;3) 引领现代化应用架构,支持微服务、容器化,内置安全机制。未来,.NET 7将带来更多新特性和前沿技术整合,如量子计算、AI,持续推动软件开发创新。开发者掌握.NET技术将赢得竞争优势。
|
13天前
|
人工智能 前端开发 Cloud Native
【专栏】洞察.NET 技术的开发趋势
【4月更文挑战第29天】本文探讨了.NET技术的三大发展趋势:1) 跨平台与云原生技术融合,通过.NET Core支持轻量级、高性能应用,适应云计算和微服务;2) 人工智能与机器学习的集成,如ML.NET框架,使开发者能用C#构建AI模型;3) 引入现代化前端开发技术,如Blazor,实现前后端一致性。随着.NET 8等新版本的发布,期待更多创新技术如量子计算、AR/VR的融合,.NET将持续推动软件开发的创新与进步。
|
22天前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
|
22天前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
|
22天前
|
存储 安全 网络安全
C#编程的安全性与加密技术
【4月更文挑战第21天】C#在.NET框架支持下,以其面向对象和高级特性成为安全软件开发的利器。本文探讨C#在安全加密领域的应用,包括使用System.Security.Cryptography库实现加密算法,利用SSL/TLS保障网络传输安全,进行身份验证,并强调编写安全代码的重要性。实际案例涵盖在线支付、企业应用和文件加密,展示了C#在应对安全挑战的同时,不断拓展其在该领域的潜力和未来前景。