威尼斯人线上娱乐

【威尼斯人线上娱乐】Net基本术语

3 5月 , 2019  

在理解vardynamic第叁字之前,让大家先精通一下编制程序语言的项目。

原文:

一、.NET Framework和C#
1.1. .NET Framework
.NET Framework具备以下职能:

C#中有两类编制程序语言:

dynamic 关键字和动态语言运维时 (DLLAND) 是 C# 四 和 Microsoft .NET
Framework 四 中的重大新添成效。 这个作用在发布时就挑起了人人的特大兴趣,并陪同着无数疑难。
同时人们也提交了好些个答案,但这个答案以后已遍及于各个文书档案以及各样本事博客和文章之中。
那样,人们在各样论坛和议会上几次三番一回又一回地建议同样的标题。

焦点术语

  • 提供了三个运作遇到,以简化软件开辟进程,下落版本争持的或许
  • 保险代码的安全实行
  • 听他们讲行当规范进行具有通讯,从而能够与非.NET代码集成
  • 让应用程序的开辟进度独立于言语与平台,确认保证各样应用程序的开销体验都以1致的
  • 提供了2个周转条件,尽或者消除了脚本语言或解释性语言的性格难题
  • 静态类型语言种类

  • 动态语言连串

威尼斯人线上娱乐,  本文全面概述了 C# 四中新扩展的动态功能,并且深入斟酌了这一个成效如何同任何语言和框架作用(举例反射或隐式类型化变量)一齐使用。
鉴于已有雅量消息可用,笔者有时会再也选拔一些卓绝示例,并提供针对性原始源的链接。
小编还将提供针对性相关内容的豁达链接,供您越发读书。

 什么是CLR?
    CL卡宴 = Common
Language
Runtime(通用语言运营时)。CL奥迪Q5是壹套标准能源,(理论上)能够被任何.NET程序所利用,而不论是选择哪个种类程序语言。它管理全部.NET程序集的实行。罗BertSchmidt(微软)在他的MSDN PDC#文章里,列举了如下CL福睿斯财富:

    1. .NET Framework包蕴组件

静态类型语言

静态类型语言也被叫作强类型语言。所谓强类型语言,通俗的讲,就是在编写翻译进度中进行项目检查的语言。大家举个简单的例子,比方大家精晓1个办法的回到类型,然则只要回去类型过于复杂,那么笔者引入您利用var。不过,当你明确明白重返类型时,恐怕重临的只是简短类型,那么作者推荐你直接行使该数据类型来声称方法重返类型,就好像平常我们日常用stringintbool等修饰符注明重回类型同样。

接下去让我们来掌握C#中的var关键字。

var要害字是定义数据类型的直接方法

当你定义特定项目标var时:

string str = "Test";  

那种写法被喻为显式类型的表明,也被喻为直接注明。

当您利用var重中之重字定义一个变量时:

var str = "Test";  

这被称之为隐式类型注明或直接类型注脚。

一般情况下,编写翻译器会在编写翻译进程中表达数据,并在编写翻译进度中创制适当的类型。在此实例中,编写翻译器将检查Test,并在生成IL代码时将var最首要字替换为字符串。

var首要字在编写翻译时静态的定义数据类型,而不是在运作时,即:1旦定义了数据类型,它将不会在运维时改动。

让我们看上边包车型大巴事例:

var str = "Test";
str = 123;  

扭转那么些应用程序,如下图所示,将在str = 123处的隐式调换抛出编写翻译错误

威尼斯人线上娱乐 1

比如将鼠标移动到第3行的str上,实际上是足以收获部分变量字符串str的值,如下图所示

威尼斯人线上娱乐 2

笔者们能够透过利用ILDasm.exe张开这个exe/dll来注明这么些结果。

  什么是“动态”?

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

  一般来讲,动态语言不执行编写翻译时类型检查,仅在运转时辨认对象的种类。
那种办法有利有弊:代码编写起来往往越来越快、更易于,但还要,由于你不会获取编写翻译器错误,只好通过单元测试和其余格局来确定保证应用程序经常运维。

  C#
最初是作为纯静态语言创设的,但 C# 肆增加了部分动态成分,用以改进与动态语言和框架之间的互操作性。
C#
团队设想了二种陈设选项,但最后分明增加3个新注重字来支持那些效应:dynamic。

  dynamic
关键字可充当 C# 类型系统中的静态类型评释。 那样,C#
就获取了动态功效,同时照旧作为静态类型化语言而存在。 若要了然怎么以及哪些做出了这么的主宰,请参考
PDC09 (microsoftpdc.com/2009/FT31)
上由Mads Torgersen 撰写的示范文稿“C# 四 中的动态绑定”。 尤其是,动态目的被断定是 C#
语言中的“一等人民”,因而并未有用来伸开或关闭动态效率的选项,并且未有向 C#
加多过类似于 Visual Basic 中的 Option Strict On/Off 之类的作用。

  当你使用 dynamic
关键字时,您就告诉编写翻译器关闭编译时检查。 网络以及 MSDN 文档中
(msdn.microsoft.com/library/dd264736)
有恢宏有关什么选取该重大字的示范。 下边是3个广泛示例:

 

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

 

  如你所见,可以将区别种类的目标分配给已评释为
dynamic 的变量。 那段代码会通过编译,并在运作时规定目标的类型。
然则,下边包车型地铁代码也会通过编写翻译,但在运转时会引发那3个:

 

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

 

  原因是一模同样的:编写翻译器不知道该目的的运转时类型,由此不或许告诉您递增操作在此境况下不受支持。

  缺少编写翻译时类型检查也会招致
英特尔liSense 成效失效。 由于 C#
编写翻译器不知晓对象的类别,由此它不可能枚举该对象的属性和办法。 正如在用于 Visual Studio 的
IronPython 工具中那样,通过附加的类型推测大概会消除此难点,但目前 C#
不提供那种类型推测。

  不过,在广大只怕受益于动态功用的方案中,由于代码应用了字符串文本而致使
英特尔liSense 如故不可用。 本文在末端将对那一标题开展更详尽的切磋。

  • 面向对象的编程模型(承继、多态、分外管理和垃圾堆采撷等) 

  •  安全模型

  •  类型系统

  •  所有.NET基类

  •  许多.NET
    framework类

  • 支付、调节和测试和评测(profiling)工具

  •  实践和代码处理

  •  IL到地头代码(IL-to-native)调换器和优化器

  • Common Language Runtime:可正是NET
    Framework的中坚,提供了起码大旨服务供应用程序行使,并肩负管理应用程序的代码。针对.NET
    Framework编写的代码成为托管代码,而任何代码成为非托管代码
  • 类库:蕴含大量可选取的类(类型),可用以支付能够想像获得的别样应用程序(Framework类库包蕴四千三个公共类,是今日最大的类库之1)
  • 并行计算平台:能够以自但是简单的措施编写高效的可扩张代码,以丰硕利用八个Computer
  • DLSportage(动态语言运转时):塑造在CL奥迪Q7的功底上,向诸如IronRuby和IronPython等动态语言提供语言服务。与诸如C#等通用语言比较,动态语言更善于实施有些职务,而动态语言运营时让您能够依照业务必要选用最合适的言语。不仅如此,动态语言运转时还让非动态语言(如C#)能够以简要而同等的语法使用动态目的,而随意这么些目标源自COM、IronRuby、IronPython依然JavaScript。

曾几何时使用var

对于像intdoublestring等简便数据类型,大家最棒使用一定的数据类型来声称变量,避防让工作变得复杂。但当您创造了3个相当的大的类,那么为了便于成立对象,你最棒使用var关键字。还有一种约定俗成的习贯,当大家应用LINQAnonymous品种时,必须运用var关键字。

  Dynamic、Object 还是 Var?

  那么,dynamic、object 和
var 之间的实在分别是什么样?几时应采纳它们? 上边是每一个入眼字的简易定义和1部分演示。

  关键字 object 表示
System.Object 类型,它是 C# 类档期的顺序结构中的根类型。 此关键字平时在编写翻译时惊惶失措分明目的类型时行使,而那种情形平常在各样互操作性情况中发生。

  您必要使用显式转变将已扬言为
object 的变量转换为一定项目:

 

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

 

  分明,那将出口
System.Int3贰。 然而,因为静态类型为
System.Object,所以您在此地须要贰个显式调换:

 

objExample =
(int)objExample +10;

  您可以给予差异门类的值,因为它们都以从
System.Object 承继的:

 

objExample =”test”

  从 C# 三.0
起,关键字 var 伊始用于隐式类型化局地变量以及无名类型。 此关键字平时与 LINQ
结合使用。 当使用 var
关键字申明变量时,就要编写翻译时依据开首化字符串猜测该变量的体系。
在运维时不可能改观该变量的种类。
要是编译器不能够预计类型,它会变卦2个编写翻译错误:

 

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

 

  那段代码会输出
System.Int3二,与静态类型同样。

  在下边的言传身教中,因为
varExample 的静态类型为 System.Int32,所以无需更动:

 

varExample =
varExample +10;

 

  上边一行不进行编写翻译,因为只好将整数赋给
varExample:

 

varExample =”test”;

 

  C# 四 中引进的
dynamic 关键字可使有个别古板上依赖于 object
关键字的气象更便于编写和掩护。 实际上,动态类型在后台使用
System.Object 类型。但与 object
不相同的是,动态类型无需在编写翻译时进行显式调换操作,因为它仅在运作时识别类型:

 

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

 

  此段代码会输出
System.Int32。

  在上面那壹行中不供给转移,因为仅在运作时识别类型:

 

dynamicExample =
dynamicExample +10;

  能够将区别类型的值赋给
dynamicExample:

【威尼斯人线上娱乐】Net基本术语。 

dynamicExample =”test”;

在 C# 常见难题解答博客 (bit.ly/c95hpl)
上,提供了关于重大字 object 和 dynamic 之间距离的事无巨细博客小说。

  有时会引起混淆的是,全部这一个关键字能够共同使用,即它们不是互相排斥的。
举例,大家来看1看上边包车型客车代码:

 

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

 

  anotherObject
的种类是怎么? 小编的答问是:dynamic。
请记住,在 C#
类型系统中,dynamic 实际上是2个静态类型,因而,编写翻译器将为 anotherObject
估量此类型。 务要求明白,var
关键字可是是一个发令,它让编写翻译器遵照变量的起首化表明式揣度类型;var
不是连串。

   
那对于.NET世界来讲意味着什么?区别程序语言的力量将比过去其余时候特别趋同,就算显著不用全部语言都能支撑具备CL福睿斯服务。

ps:动态语言:在比方C#等利用静态类型的语言中,由编写翻译器鲜明项目安全,假使不能明确,就将生成错误。在动态语言中,不会尝试分明项目安全。其余,大大多动态语言在运行阶段执行更复杂的体系操作,如判别方式重载是不是科学,而C#在编写翻译阶段做出那种论断。

动态类型语言

动态类型语言是指在运转时进行项目检查的言语。假若您不知底您将收获或须求分配的值的类型,则在此情景下,类型是在运转时定义的。让大家看看上边的例证。

class Program {  
    static void Main(string[] args)
    {   
        dynamic str = "Test";  
    }  
} 

现行反革命,假诺您输入str.,那么您将无法得到任何智能提示,如下图所示。

威尼斯人线上娱乐 3

此例中,在为str分配值之后,假设实行一些数学运算,它不会交到任何错误信息。

class Program {  
    static void Main(string[] args) 
    {  
        dynamic str = "Test";  
        str++;  
    }  
}

很强烈,以后尽管作者生成应用程序,也不会有不当发生,应用程序也会大功告成转移:

威尼斯人线上娱乐 4

不过,假如您运转这一个应用程序,对不起,VS会给你如下所示的周转时不当:

威尼斯人线上娱乐 5

dynamic首要字里面采纳反射,感兴趣的童鞋能够自动钻研一下。

  动态语言运维时

  说起 C#
语言景况中的“dynamic”这壹术语,它平日指上面五个概念之一:C# 四 中的
dynamic 关键字或 DLGL450。 就算那八个概念是荣辱与共的,但也亟供给明白它们之间的差距。

  DL奥迪Q7有八个重大目标。 首先,它达成动态语言和 .NET
Framework 之间的互操作。 其次,它将动态行为引进 C# 和
Visual Basic 之中。

  DL福睿斯的开创吸取了营造 IronPython (ironpython.net)
时的经验教训(IronPython 是在 .NET Framework
上完结的首先种动态语言)。 在创设 IronPython
时,专业集体开采他们能够针对二种语言重复使用他们的兑现,由此,他们为
.NET 动态语言创立了二个集体基础平台。 与 IronPython 同样,DLPRADO已化作二个开源项目,其源代码近年来在dlr.codeplex.com
上提供。

  后来,.NET
Framework 4 中也纳入了 DLHaval,以帮衬 C# 和 Visual Basic
中的动态效率。 假若您只须求 C# 4 中的
dynamic 关键字,那么使用 .NET Framework 就足以了。在大部分气象下,仅凭
.NET Framework 就能够管理与 DLGL450 之间的全数交互。 可是,如若您愿意完结新的动态语言或将其搬迁到
.NET,则能够收入于开源项目中附加的推抢程序类,该开源项目为语言完毕人口提供了越来越多效益和服务。

 

1.3.关于.NET Framework

小结

vardynamic最首要字中间的重要区别在于绑定期期不均等:var是早先时期绑定,dynamic绑定则会在运行时举办。

var实质上是编写翻译器抛给大家的语法糖,一旦被编写翻译,编译器就能够自动相配var变量的实际上类型,并用实际类型来替换该变量的表明,等同于大家在编码时行使了实在类型注明。而dynamic被编译后是三个Object品种,编译器编译时不会对dynamic实行项目检查。

.Net
4.0事先的运维时的动态调用一般是经过反射来促成,然而反射的代码的可读性不高。.Net
四.0自此选取dynamic就好得多,因为dynamic是壹种静态类型,完全能够像其余连串同样的评释和调用,而不用写反射相关的代码。

理所当然的使用dynamic能够让你的代码越发的洗练,而且比一直动用反射品质越来越好(反射没有优化管理的前提),因为dynamic是基于DLR,第三遍运维后会缓存起来。其实有心的同学会发掘.net的类Curry面诸多地方都用了dynamic本条东西,举个例子:mvc中的ViewBag正是一个很好的例子。一般景观下,如若开荒者不了然方法和格局的归来类型是还是不是公开,请使用dynamic关键字。

 作者:阿子
 博客地址:
 本文地址:
 注脚:本博客原创文字允许转发,转发时务必保留此段注脚,且在小说页面显著地点给出原来的小说连接。

  在静态类型化语言中选择 Dynamic

  大家并不愿意种种人都真心实意选拔动态而不是静态类型注明。
编写翻译时检讨是2个强硬的工具,对它的应用过多。
而且,再度建议,C#
中的动态目的不支持 速龙liSense,那对完全工效可能会有个别影响。

  同时,在产出
dynamic 关键字和 DLCR-V 在此以前,有部分方案在 C# 中曾经难以落成。
在在此在此以前的大部场馆下,开采职员使用
System.Object 类型和显式调换,一样不可能很好地采纳编写翻译时检查和
AMDliSense。 上面是有的例证。

  人们最纯熟的2个情景是,有时必须运用
object 关键字来落到实处与此外语言或框架的互操作性。 常常,您必须正视反射来获取对象的花色以及走访其性情和方式。
语法有时难以阅读,由此代码难以有限援救。
此时利用动态功能大概比选用反射特别便于和有益。

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

 

object calc =
GetCalculator();

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

  该函数重临2个总计器,但系统在编译时不清楚此计算器对象的确切类型。
代码所依赖的并世无双事情是此目的应怀有
Add 方法。 请注意,此形式不能选择AMDliSense,因为您以字符串文本的格局提供了艺术名称。

  使用 dynamic
关键字,代码就很轻便了:

 

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

万一情状未有成形:存在某种大家目的在于其持有 Add 方法的茫然类型的对象。
与上贰个示范一样,此措施也无法接纳IntelliSense。 但语法阅读和接纳起来要轻便繁多,看上去就好像在调用八个普通的
.NET 方法。

MSIL :

针对.NET
Framework编写的代码称为托管代码,而依据那几个代码生成的应用程序称为托管应用程序。托管应用程序运维时,将机关承载(
host )相应的公共语言运转时。.NET Framework
不仅提供了大气的周转时宿主,还提供了力所能致编写宿主的工具。那样,诸如Internet音讯服务(IIS)和Microsoft
SQL
Server等非托管应用程序也可承载公共语言运营时备份,从而能够运用托管职能和非托管功用。

  动态方法包

  能够应用动态功效的其它1个事例是创设动态方法包,动态方法包就是可在运营时加上和删除属性及措施的靶子。

  .NET Framework 四有一个新的命名空间:System.Dynamic。 此命名空间实在是 DL科雷傲的1有的。 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 瓦格纳撰写的小说“动态方法包”(msdn.microsoft.com/library/ee658247)
以及 C# 常见难题解答博客小说“C# 4.0 中的 Dynamic:ExpandoObject
简介”(bit.ly/amRYRw)。

    微软中路语言,Microsoft Intermediate Language。

威尼斯人线上娱乐 6

  类包装

  您可认为和煦的库提供越来越好的语法,或为现存库创造包装。
与前多个方案比较,那是二个更加高档的方案,并且必要对
DLTiggo 具体内容有越来越尖锐的摸底。

  对于简易意况,能够使用
DynamicObject 类。 在那个类中,能够将艺术和总体性的静态注脚与动态调整举行混合。
那样,您就足以在3个类属性中蕴藏三个要为其提供更佳语法的对象,但经过动态调解来处理针对该目的的全部操作。

  举例,请看一下图 第11中学的 DynamicString
类,该类包装了贰个字符串,并在经过反射实际调用全部办法以前显示这个格局的名号。

1 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;    }  }}  
2  
3  
4   若要实例化该类,应使用 dynamic 关键字:
5  
6  
7  
8 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
类是由 DL宝马7系 提供的。 生成动态目的所要求的唯有是
DynamicObject 或 ExpandoObject。 不过,某些动态目的具备用于访问成员和调用方法的盘根错节绑定逻辑。
那种对象供给完成IDynamicMetaObjectProvider 接口并提供其自个儿的动态调解。 那是①种高等方案,感兴趣的读者可以读一下由
Bill Wagner撰写的篇章“实现动态接口”(msdn.microsoft.com/vcsharp/ff800651),以及由
亚历克斯 特纳 及 Bill Chiles 撰写的小说“库创作者 DLLAND入门”(dlr.codeplex.com)。

   
全数的.Net语言编写翻译器都生成它。那是编写翻译器生成的二进制代码的公共标准,是CLEnclave实施的语言。CLSportage也定义存款和储蓄程序集的元数据的格式,那象征不管接Nash么语言编写,全部的顺序集都共享存款和储蓄元数据的公其格式。

Paste_Image.png

  可编写制定脚本的应用程序

  脚本是向应用程序提供可扩大性的壹种庞大方法。
Microsoft Office
可作为那方面包车型客车3个好例子:由于 Visual Basic for Applications (VBA)
的存在,能够利用大量的宏、加载项和插件。 未来,DL瑞鹰提供了一组公用的言语宿主
API,由此可让您创制可编写制定脚本的应用程序。

  举例,您能够成立一个应用程序,使用户能够团结在里面加多效果而无需主产品提供新效率,例如向游戏中增添新的字符和照耀,或向业务应用程序增多新的图样。

  您必须运用来源
dlr.codeplex.com 的开源版 DL宝马X5 而不是由 .NET
Framework 四 使用的 DLSportage,因为 DL奥迪Q叁 脚本编写和宿主 API
未来仅在开源版中提供。 别的,假定的场合是您不是采纳C# 编写脚本,而是选拔1种 .NET 动态语言(如 IronPython 或
IronRuby)来编排。 不过,实际上任何语言都得以援救那一个API,包括不是在 DL本田CR-V 之上完毕的言语。

  有关使用此功效的详细新闻,请观看PDC0九 (microsoftpdc.com/2009/FT30)
上由 Dino Viehland
所做的示范“使用动态语言生成可编写制定脚本的应用程序”。

 

该图表达了.NET
Framework的逐条零部件与应用程序、操作系统和非托管应用程序之间的涉及。

  识别动态目的

  怎么着区分动态目的与别的对象?
一个方便人民群众方法是使用内置的 IDE
作用。 您能够将鼠标光标悬停在对象上以查看其宣称类型,或检查
速龙liSense 是还是不是可用。

威尼斯人线上娱乐 7

只是在运维时,意况会变得尤其错综复杂。 您无法检查变量是或不是是通过
dynamic 关键字注脚的 —
动态目的的运作时类型是它所蕴藏的值的体系,您无法得到其静态类型注解。
那种情景与将变量申明为
object
时的状态一样:在运维时,您不得不获得变量所蕴藏的值的项目;不能够剖断此变量最初是或不是注解为
object。

  运营时所能分明的是目的是否来自
DLCRUISER。 知道那种情景恐怕格外首要,因为像
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);// Truedynamic test = "test";Console.WriteLine(test is IDynamicMetaObjectProvider);// False

 

故而,假设将动态功效与反射一同使用,则请牢记,反射不适用于动态增加的习性和艺术,并且最佳检查正在反射的靶子是或不是落到实处了
IDynamicMetaObjectProvider 接口。

什么是CLS?

1.4.CLR
CL福睿斯是.NET
Framework的着力,提供了3个集合类型系统和2个托管运营条件,为付出和执行独立语言和平台的应用程序打下了基础,还带动清除(至少是减弱)众多相近的BUG

  动态功效与 COM 互操作

  C# 团队在 C# 四版本中特地思量的 COM 互操作方案是本着 Microsoft Office 应用程序(如 Word
和 Excel)进行编制程序。 他们的目标是让这一职分在 C#
中变得像在 Visual Basic 中那么轻易和自然。 那也是 Visual Basic 和 C#
共同提高政策的一有的,这么些政策目的在于贯彻两种语言的效果对等,并互相借鉴最棒、最具效能的减轻方案。

  若需驾驭详细新闻,请参阅
斯科特 威尔特amuth 的 Visual Studio 博客文章“C# 和 VB
共同升高”(bit.ly/bFUpxG)。

  展现了一段 C# 四代码,该代码向 Excel 职业表的率先个单元格中加多二个值,然后向第一列应用
AutoFit 方法。 每行上边包车型客车笺注展现了 C# 3.0
及更早版本的中的等效代码。

1 // 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(); 
2   此示例有趣的地方是,您在代码中的任何位置都看不到 dynamic 关键字。实际上,该关键字仅在下面一行中用到:
3  
4  
5  
6 targetRange.Columns[1].AutoFit();// ((Excel.Range)targetRange.Columns[1, Type.Missing]).AutoFit();

 在 C# 3.0 版中,targetRange.Columns[1, Type.Missing] 重返object,那就是急需向 Excel.Range 转变的来头。 但在 C# 四 和 Visual Studio
20十 中,那样的调用将以沉默形式转变为动态调用。 因而,C# 4 中
targetRange.Columns[1] 的种类实际上是 dynamic。

  另一个鼓起特征是,C# 四中的 COM 互操作革新不只限于 dynamic。 由于其他一些骤增功效(例如索引属性以及命名参数和可选参数),其余全部行中的代码也有所立异。
由 Chris Burrows
撰写的 MSDN 杂志 小说“.NET Framework 四 中的新扩展 C#
功能”(msdn.microsoft.com/magazine/ff796223)
中对这几个新扩展功能做了很好的概述。

    CLS = Common
Language
Specification(通用语言专门的学业)。它是CTS的二个子集,全数.NET语言都将支持它。任何利用CLS包容的类型的次序,都得以和以其余语言编写的.NET程序举办互操作。其成效是在具备与CLS兼容的言语(c#,Visual
Basic的.Net版本,Visaul
C++或任何的.Net语言)中编辑的顺序都共享组件,这几个零件具备跨各个语言界限的一点壹滴承继性。CLS定义了言语必须支持的效能,以支撑与其余.NET语言的交互性。还是能运用CLS中从不的效用,但无能为力确认保障其余语言也补助那此效用。

1.四.一 通用项目系统
Common Type
System,CTS让全体.NET语言共享同样的类型定义,那样便能够一样的办法操作那些项目,有助于保障准确地编写应用程序
原因如下:

  从何地能够博得越多音信?

  希望本文已带有您对
C# 4 中的 dynamic
关键字只怕部分抢先50%问号,但自己坚信本文并非八面后珑。 倘诺你有观念、难题或提议,敬请光临
dlr.codeplex.com/discussions
提议。 别的人恐怕早就提过您关心的标题,可能你能够倡导新的座谈。
我们有着1个活跃的社区,迎接新成员加入。

理论上,那允许在分歧的.NET语言之间展开丰裕严厉地互操作。比方说,允许二个C#类从二个VB类承继下去。

  • 破除了将不匹配的数据赋给类型的恐怕
  • 每一种.NET语言的项目描述都平等,而随意用于定义该类型的言语是怎么着
  • 以平等的措施操作类型

 

ps:类型安全和CTS
通用项目系统和集体语言职业为.NET Framework类型安全打下了稳固的底子。
那让.NET
Framework可以以同等的章程倡导类型安全,而没有要求强制实践类型安全。强制实行类型安全的天职留给了语言编写翻译器和稍后将介绍的杜撰施行系统。
通用语言种类以单独于言语的主意定义类型,由此它必须思量这个语言之间的差别。通用语言系统提供了一个最基本的规则集,全部.NET语言及其编写翻译器都不能够不信守,那么些规则集称为公家语言专门的学问(Common
Language
Specification,CLS)。那种通用定义让语言集成成为大概:使用另1种语言中定义的花色,就好像它是在时下语言中定义的同1。

 

ps:CLS遵从性
差那么一点Framework类库中的全数类都符合CLS,因而任何.NET语言都可利用这么些类库。假诺要开垦和煦的类库,那么建议保险那一个类也契合CLS,那样它们才具博取最普及的行使。

 什么是CTS?

1.四.二 通用中间语言
通用项目系统和集体语言职业有助于达成独立于言语和平台的靶子,可是即使编写翻译器生成的可施行对象代码注重于硬件平台,那么它们带来的裨益将未有殆尽。为缓和那几个主题素材,将托管代码举行了一部分编写翻译,以转换使用1种低等语言的代码,那种语言称为通用中间语言(Common
Intermediate
Language,CIL)。通用中间语言类似于汇编语言,由代表高等语言代码的起码指令组成。

    CTS = Common Type
System(通用项目系统)。那是.NET运营时亦可领略的一大套花色,由此,.NET应用程序就足以应用它们。然而要留意,并不是全数.NET语言都帮衬CTS中存有类型的。CTS是CLS的两个超集。它定义由全体.NET语言使用的主导类型,以及定义本人的类的条条框框。那足防止范不相配方式实现语言(比如string类型)

次第集(assembly)是部分编写翻译单元(包),包罗CIL指令并为定义类型提供了逻辑边界。由于程序集是有的编译的,因而得以是3一位的,也能够是陆十人的,那有赖于操作系统和硬件。那表示托管应用程序是单独于阳台的,且无需另行编写翻译或抬高特殊指令就能够丰盛利用硬件技艺。

 

一.四.三 虚拟实行系统
集体语言运转时的另1个关键组成都部队分是托管运营条件,那种条件称为虚拟推行系统(Virtual
Execution System,VES),它担任处理应用程序所需的初级宗旨服务。就像是Java应用程序须要有 Java 虚拟机(JVM)才干运维一样,托管应用程序也亟需有
CLOdyssey(具体地说是VES)才具运转。

 

.NET应用程序运行时,由VES负担加载并进行CIL代码,并处理应用程序所需的内存分配。换句话说,VES提供劳务和基本功设备,从而解除平台和言语差距带来的影响。

 什么是IL?
    IL = Intermediate
Language(中间语言)。也称为MSIL(Microsoft Intermediate
Language,微软个中语言)或CIL(Common Intermediate
Language,通用中间语言)。全体.NET源代码(不管用哪类语言编写)都被编写翻译成IL。当软件被安装时,IL转变为机器码,或在运维时被即时
(Just-In-Time,JIT)编写翻译器所管理。

在加载和编写翻译进程中,VES推行各个评释,以管教育和文化件格式、程序集元数据和CIL是一模同样的,并保管CIL指令不可能违法访问内部存款和储蓄器。那样,应用程序将只可以访问它被授权访问的内部存款和储蓄器和能源。可将那种受限的条件正是沙箱(sandbox)。

 什么是C#?
   
C#是微软设计的一门新语言,用于和.NET
framework合作。在它的白皮书《C#介绍》(“Introduction to
C#”)中,微软是那般描述C#的:
   
“C#是一门派生于C和C++的轻易、今世、面向对象和项目安全的程序语言。C#(发音C
sharp)加强地植身于C和C++语言家族树中,并将相当慢为C和C++技士所熟稔。C#目的是将Visual
Basic的高生产力和C++的原生威力联合起来。”
把上边一段话中的“C#”用“Java”代替他,你会意识那一个说法依然挺好

既然如此VES提供了运营情形并进行李包裹涵CIL的程序集,那么那一个程序集是解释型如故编写翻译型的啊?别忘了,.NET
Framework的靶子之壹是提供这样的运营条件:最大程度地回落乃至裁撤脚本(解释型语言)的质量难点。那意味CIL代码是编写翻译型的,VES
提供的劳务之壹是霎时(Just-In-Time,JIT)编写翻译器。即时编写翻译指的是在运维阶段将经过部分编写翻译的CIL代码调换为可进行的靶子代码(本机代码)。

 在.NET意况下,“托管(managed)”1词的意思是?
   
术语“托管(managed)”是多多益善狼藉发生的导火线,在.NET中,它被用于多数例外的地方,所抒发的东西有所细微的距离。
    托管代码(Managed code):.NET
framewor为运维在它里面包车型客车次第提供了数个核心运营时服务,举例相当管理和安全。为了使那个劳动能够运维起来,代码必须向运营时提供最起码的新闻,
那样的代码被喻为托管代码。暗许来说,全数C#和Visual
Basic.NET代码都是托管的。VS7C++代码缺省来讲不是托管的,但足以经过点名命令行开关(/com+),使编写翻译器生成托管代码。

ps:即时编写翻译
当即编写翻译进度被叫作jitting,而JIT编写翻译器被称为jitter。

    托管数据(Managed
data):那个数据由.NET运营时垃圾收罗器举办配置和消除。C#和VB.NET数据连接托管的,暗许来讲,VS7C++数据是非托管的,纵然接纳/com+按键也是那样,但能够用__gc关键字将其标记为托管的。

通过以那种格局编写翻译代码,.NET
Framework得到了比守旧解释型语言高得多的速度。相对于健康(静态)编写翻译,即时编写翻译也有优势,因为它可在进度。相对高璇常(静态)编写翻译,即时编写翻译也有优势,因为它可在运作阶段实施安全保持,还可在运营阶段重新编写翻译以越来越优化代码。.NET
Framework
JIT编写翻译器进行了可观优化,以便将CIL代码编写翻译成高效的对象代码;它在急需时运营,并缓存编写翻译后的代码供现在使用。

    托管类(Managed
classes):通常在C++托管扩张(Managed Extensions for
C++)背景下谈及那么些术语。当使用ME
C++时,种类可标以__gc关键字。正如名字所暗中提示的,那意味着那几个类的实体所占有的内存由垃圾采撷器托管,但意思还不只于此。那些类成为了三个全然交
付给.NET大家庭的成员,它可享受.NET所拉动的功利,同时也受.NET施加的关于制裁。关于好处的叁个例证是足以和任何语言编写的类很好地互操作,
比方,3个managed
C++类可以接二连三自一个VB类。关于约束的三个例证是,托管类只好再而三自三个基类。

一.四.4 内部存款和储蓄器管理和废品搜集
.NET
Framework让VES自动分配和回收内部存储器,那种活动内部存款和储蓄器管理称为垃圾收集,正是它让C#(和其余.NET语言)成为1种垃圾搜罗语言。垃圾收罗令你无需过多地为刑满释放解除劳教无需的内部存储器而想不开,它幸免了繁多大规模的编制程序错误,让您创立的应用程序更平稳,并可根本关怀应用程序所需的工作逻辑。

 什么是反光(reflection)?
    全体.NET
编写翻译器都为它们生成的模块(modules)中所定义的档案的次序发生元数据(metadata),这一个元数据和模块打包在共同(模块被打包于配件
(assemblies)之中),并可因此反射机制(reflection)存取。System.Reflection名字空间中包罗的类,能够用来“查
询”模块/配件的类型。
   
使用反射来存取.NET元数据,十三分周边于接纳ITypeLib/ITypeInfo存取COM中的类型库数据,并且,它被用于类似的用处,比如说,决定数据类型尺寸,以用来超越上下文/进度/机器边界列集(marshaling)数据。
   
反射还足以用于动态调用方法(methods)(参见System.Type.InvokeMember),或在运作时刻动态创设类型(参见System.Reflection.Emit.TypeBuilder)。

纵然有了电动内部存款和储蓄器管理,精晓垃圾收罗器怎么着与程序以及你成立的门类交互也很重大。

什麼是强类型定义语言?
强类型定义语言:强制数据类型定义的言语。也正是说,一旦1个变量被内定了有些数据类型,倘使不经过强制调换,那么它就恒久是

1.5 Framework类库
即便CL汉兰达是.NET
Framework的着力,但确实赋予它力量的是Framework类库(FCL)。那个类库类似于Java类库、C++标准模板库(STL)、Microsoft活动模板库(ATL)、Microsoft
Foundation Class(MFC)、Borland对象窗口库(OWL)及其它类库。

什麼是弱类型定义语言?
 
1类别型可以被忽视的语言,与强类型定义相反。VBScript是弱类型定义的。在VBScript中,能够将字符串  
‘1二’   和整数   三   进行延续获得字符串   ‘1二三’,然后能够把它当做整数  
1二三,而没有须求出示调换。

与那一个类库一样,FCL也暗含大批量可采取的档次,那简化了很多广泛的编制程序职分,从而提供了支出作用。

什麼是动态类型语言?
动态类型语言:动态类型语言是指在运作时期才去做数据类型检查的言语,也便是说,在用动态类型的语言编制程序时,永远也不用给任何变量内定数据类型,该语言会在你首先次赋值给变量时,在其上将数据类型记录下来。Python和Ruby就是一种规范的动态类型语言,其余的种种脚本语言如VBScript也某个属于动态类型语言。

威尼斯人线上娱乐 8

什麼是静态类型语言?
静态类型语言:静态类型语言与动态类型语言恰恰相反,它的数据类型是在编写翻译时期检查的,也正是说在写程序时要表明全部变量的数据类型,C/C++是静态类型语言的卓越代表,别的的静态类型语言还有C#、JAVA等。对于动态语言与静态语言的分别,套用一句流行的话便是:Static
typing when possible, dynamic typing when needed。

Paste_Image.png

怎么是壹元操作符?
是唯有一個操作數的操作符。如遞增操作符(++)。

该图列出了FCL中的一些档期的顺序,并按成效对它们举行了编组

怎么是二元操作符?
是要示有兩個操作數的操作符。如乘法操作符(*)。

ps:固然不采取 FCL 提供的品类也足以创设应用程序,但其实不容许那样做。

DCOM:
Distributed Component Object Model,DCOM:分佈式組件對像模型

在最尾巴部分是基础类库(Base Class
Libraries,BCL),它们充当全体.NET语言的正统运转条件,提供的类型可代表CLRubicon类型、集结、流和别的数据结构,可用来操作字符串、试行基本的公文存取和各个其余操作。BCL总共有17二种公有类型,而Ecma-335 标准(Common Language Infrastructure (CLI), 四th
艾德ition)定义的标准库总共有 33壹种公有类型。

SOAP:
Simple Object Access
Protocol,SOAP:簡單對像訪問協議。焦点是增加跨平台的互操作性。

CLI是公私语言运营时(Common Language Runtime)的开源版本。在Ecma
的砥砺下,开荒了 C#和.NET Framework
的多少个开源版本,包含DotGNU和Mono。在这之中最知名的或者是Mono,它提供的.NET开采平台落成可用于Linux、BSD、UNIX、Mac
OS X、Solaris和Windows操作系统。

WSDL
Web服務描述語言:Web ServiceDescription Language,WSDL。Web服務的ULANDL後綴名為.asmx

FCL 中的其余类关心的都是一定作用,如提供数据访问、XML
帮助、整个世界化帮忙、会诊、配置、联网、通讯、业务流程帮衬、Web应用程序和Windows桌面应用程序等。

序列化:
SOAP允許小编們在客戶端應用程序和Web服務之間傳遞複雜的數據結構。你能够選擇以輸入參數、輸出參數大概重临值的样式來傳遞。為此數據結構本人要轉換成能通過網絡傳輸並在另一端重新組裝的格式。這個過程稱為「种类化」

一.伍.一 命名空间

鉴于.NET
Framework类库包涵数千个类,要求动用某种形式防止类名混淆,并提供一种方便人民群众的层系编组机制。为此,.NET
Framework接纳了命名空间的概念。命名空间但是是一系列项目,对项目标可知性未有任何影响。命名空间可含蓄八个程序集。.NET
Framework使用档次型命名空间提供了3个渐进型框架,创设出了一个作用庞大而又便于使用的花费平台。

ps:命名空间和等级次序名
取名空间利用点分式语法表示档期的顺序结构,每层之间都用句点(.)分隔。

在档案的次序的1体化名称中,以最右侧的句点为分界点,左边是命名空间,而右边是项目名。比方,
System.Printing.PrintDriver
是位于命名空间System.Printing中的类型PrintDriver的完好名称。

唯独,只有.NET编制程序语言援救命名空间。在CL途锐中,类型总是用全部名称标记,在那之中包罗类型的名目及其所属的命名空间。

威尼斯人线上娱乐 9

Paste_Image.png

常用命名空间

一.伍.二 并行总结平台
那是1种斩新的编制程序模型,适用于托管代码和非托管代码。它提升了聊以自慰程度,不需求考虑十分的低端的定义,如线程和锁定。

对于托管代码,并行计算平台提供了广泛循环指令的相互达成和LINQ to
Objects的相互落成,还新添了可防止死锁的线程安全群集。

并行总计平台简化了那样的体制:编写可连忙利用多个Computer的代码。要分明怎么着的代码适用于并行总计,仍亟需开始展览解析

1.5.3 DLR
DLOdyssey 建设构造在公私语言运转时的基本功之上,那代表动态语言可与其他.NET
语言集成。DL索罗德 还让现成的静态语言(如
C#)可以辅助动态作用,那让它们能够以同等的办法利用动态目的,而任由这一个目标来自哪里。
有了 DL奥德赛前,便可帮助动态语言,而静态语言也可使用动态作用。那样,开辟职员就可依据要消除的标题选择最合适的言语,且制造的动态代码可供别的开采职员和.NET语言轻巧地动用。

二、C#语言
2.1 类型
在C#中,类型是对值的讲述。每当必要二个值时,就须求一种等级次序。类型定义了同意的值以及那几个值协理的操作。在C#中,各样值都由其所属的门类周到描述,且是其所属体系的三个实例。所谓全面描述,指的是种类显明地钦点了值的代表方法以及可对它实践的操作。

C#品种分为两类:
值类型和引用类型。值类型描述的值是截然独立的,那包罗数值类型、枚举类型和布局;
引用类型存款和储蓄指向值的引用,而不是值作者

C#提供了广大预订义的值类型和二种预约义的引用类型,还能创建用户定义的门类。只需掌握一个最重大的歧异:值类型包蕴实际值,而引用类型涵盖指向实际数目标引用。

二.贰 语句和表明式
话语是一条完整的次序指令,必须以分集团(;)结尾。每条语句中不得不分包一条指令,那看起来限制性很强,但C#还提供了语句块,那是壹组用大括号括起的言语。在能够应用单条语句的别的地方都可应用语句块。
鉴于语句以根据地结尾,因而可应用空白(如空格、制表符和换行符)调度代码的排列形式。最好的章程是应用1种简单而同等的风骨,让代码更便于阅读和保安。

ps:尽管编写翻译器常常忽略空白,可是项目表明、标记符和任何关键字中间的空域很重要。若是未有空白,编写翻译器将不能辨认关键字。

表明式的结果为值。假诺将讲话视为操作,那么表明式就是计量。结果为布尔值(true或false)的发表式常用于判定规范是或不是满意,那种表明式称为布尔表明式

二.三 变量和常量
对此变量,最简便的概念是它代表几个仓库储存位置,个中的值可随时间流逝而生成。最常见的变量是某个变量和字段,它们都可通过点名项目、标志符和可选的初值来定义:
int a;
int b = 1;
要是要注解七个门类一样的变量,就可将宣示合并在同步,如下所示:
int a, b;
在限定功效域(如方法)内评释的变量称为局地变量,只辛亏该功能域内通过名称访问它。

ps:功效域、生命空间和寿命
可将效用域视为容器,唯有在该容器内才具透过非限定名合法地走访变量。那不一致于评释空间,在表明空间内,不容许有八个名称一样的标志符。假设说成效域钦点了您在哪儿能够利用有些名称,那么注脚空间就建议了该名称在哪里是独占鳌头的。
变量的寿命与其功效域紧凑相连,它决定了变量在多久内可用。只要当前奉行的代码还放在变量的意义域内,该变量就可用。

字段是在限定效率域内注明的变量,它依然与项目作者相关联,要么与项目标几个实例相关联。在前一种情景下称为静态变量(可将其身为一种全局变量);在后壹种情状下则名称叫实例变量。使用一些变量和字段在此以前,必须将其起首化;其余,只有在那个变量的扬言所属的代码块内才具访问它们。

代码:

class Color    
    {        
        private byte red;        
        private byte blue;        
        private byte green;        

    public Color(byte red, byte blue, byte green)        
    {            
        this.red = red;
        this.blue = blue;
        this.green = green;        
    }        
        public static Color White = new Color(0xFF,0xFF,0xFF);
        public static Color Red = new Color(0xFF,0,0);
        public static Color Blue = new Color(0,0xFF,0);
        public static Color Green = new Color(0,0,0xFF);
    }

ps:使用静态字段之前,须求对其张开开始化,可是随后不可能确定保障它们的值不会变卦。为了注解初始化后就无法改改的字段,能够创立只读字段。

只读字段的Color类代码如下:

    class Color
    {
        private byte red;
        private byte blue;
        private byte green;

        public Color(byte red, byte blue, byte green)
        {
            this.red = red;
            this.blue = blue;
            this.green = green;
        }

        public static readonly Color White = new Color(0xFF,0xFF,0xFF);
        public static readonly Color Red = new Color(0xFF,0,0);
        public static readonly Color Blue = new Color(0,0xFF,0);
        public static readonly Color Green = new Color(0,0,0xFF);
    }

ps:常量表示在编写翻译阶段可总结的值。常量与项目作者相关联,就好像静态的。与变量同样,常量可在限制效率域内注明,也能够是大局的;与变量不一样的是,必须在宣称常量时对其进行起头化。

ps:字面值和魔数
字面值平时是有分外含义的数值,并在代码中央直机关接钦赐。随着时间的延迟,也许忘记字面值的含义,导致相应的代码难以保险。由此,那个字面值常被号称魔数(magic
numbers)。通过选取常量而不是字面值,可将其含义保留下来,让代码的意义不言自明。

    static float Compute(float f1)
    {
        const float SpeedOfLight = 299792458

            return SpeedOfLight / f1;
    }

扬言变量或常量的话语日常号称证明语句,可放在代码块的别的地点。

二.肆 标志符和首要字
注解变量、字段或常量时,必须内定数据类型并提供有含义的名目,后者成为标志符

标记符遵循的平整:

  • 只得分包字母(大写和题诗)、数字和下划线
  • 标志符必须以字母或下划线打头,但对于国有标记符,以3个或几个下划线打头是壹种倒霉的做法,应防止那样做
  • 在加以的宣示空间内,标志符必须是无与伦比的
  • 标志符是分别轻重缓急写的

选取标记符时,应遵从的其他知道原则如下:

  • 标记符应易于阅读
  • 标志符应使用缩写
  • 标记符应提供尽恐怕抬高的含义

C#中,标识符是分别轻重缓急写的。推荐的命名约定如下:

  • 对于变量名和参数名,使用Camel大小写规则,该规则供给除第二个单词外,其余单词的首字母都大写
  • 对此方法名和其余标记符,使用帕斯Carl大小写规则,该规则供给各样单词的首字母都大写

ps:Camel和Pascal大小写规则
选取Camel大小写规则时,标记符中的大写字母看起来向驼峰,那种大小写规则因而而得名。帕斯Carl大小写规则因其被Pascal编制程序语言分布使用而得名(Turbo
帕斯Carl语言最初是由Anders设计的)。
Microsoft不再推荐应用Hungarian表示法,也不引入应用下划线分隔单词,那二种表示法在其它语言中很常用。

ps:C#中有捌十三个标志符在别的情形下都属于主要字

威尼斯人线上娱乐 10

Paste_Image.png

威尼斯人线上娱乐 11

Paste_Image.png

ps:还有2伍个关键字改成上下文关键字,它们仅在特定情景下(上下文)中有异乎平日意义

威尼斯人线上娱乐 12

Paste_Image.png


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图