Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the new feature Dynamic in .NET 4.0?

2025-01-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail what the new .NET 4.0 feature Dynamic is. The editor thinks it is very practical, so I share it with you as a reference. I hope you can get something after reading this article.

Some time ago, I read about dynamic, a new feature in dynamic 4, and saw that some friends think that it does more harm than good, such as unable to use compiler smart tips, unable to do static type checking at compile time, poor performance, and so on. Therefore, in this article, I will make a more detailed introduction to dynamic on these issues. I hope that through this article, we can have a deeper understanding of the dynamic keyword.

Dynamic introduction

I'm sure many of you already know something about Anders Hejlsberg's "The Future of C #" post on PDC2008, which introduced some of the most important features of Craft 4.0. When Anders mentions the future of C #, he points out that dynamic programming is the feature of Craft 4.0. He also cited many examples of dynamic programming in 4. 0. Here I'll talk about the dynamic keyword he first mentioned.

When it comes to dynamic, the first thing that comes to mind is the var keyword. In fact, when var just appeared in Category 3.0, it was questioned by some people. Microsoft later explained that var is only an implicit type declarant and can only be used as a local variable. In fact, it is still strongly typed, but the compiler infers from the initialization results, so you can still use VS hints for this variable. Now dynamic has really taken a big step towards dynamic characteristics. According to Anders, dynamic refers to dynamic static types, that is to say, it is still static in nature, but it tells the compiler to ignore its static type checking, it will only do type checking at run time, and it can be applied to almost all C # types, such as methods, operators, indexers, properties, fields. It actually invokes methods, properties, and other operations in a unified way.

Dynamic is mainly used in situations that need to interact with the outside world (COM,DLR,HTML DOM,XML, etc.), at these times, you may not be able to determine the specific type of these objects and only know some of its properties, such as methods, so these times you only tell the compiler that you need to execute these methods where the program is running, as for what the operation object is, you may not care. At this point, static types can't help you solve the problem, because they are decided at compile time, and reflection can be bigger, but it's too cumbersome and inefficient. So dynamic appears at the right time, at the cost of missing type checking at compile time to implement code that makes programmers look clean.

The declaration and use of dynamic is simple and basically consistent with var in javascript. It is important to note that before compiling the code, we first need to install VS 2010 Beta2 or Visual C # Express 2010, which I have installed here is C # Express (Note 2). E.g. Code 1:

Class Program {static void main () {dynamic axiaError = "Error"; a = "Test"; a.Run ();}}

This code can be compiled, but cannot be run. The C # compiler allows you to call any method or other member on the an object. It does not check whether these member calls are legal at compile time. Instead, the compiler checks whether the actual object has the corresponding method at run time, and if so, calls it. Otherwise, CLR will throw an exception. For example, the following code will execute normally:

Static dynamic Sum (dynamic obj1,dynamic obj2) {return obj1.Age+obj2.Age;} static void main () {var animal=new {Sex= "Male", Age= "5"}; var plant=new {Class= "herbs", Age=100}; dynamic ageCount=Sum (animal+plant);}

Here we add the ages of two different objects. In the sum function, we don't care what the object we call is, we just need to know that they all have an Age member and that this member can operate on the + operator. In fact, there will be a large number of such scenarios in interaction with DLR and Silverlight, so dynamic will be very useful in these situations.

After exploring the use of play, let's take a look at how dynamic is implemented. In fact, if you look at the code through Reflector, you will find that the code it displays looks like this:

Internal class Program {/ / Methods private static void Main (string [] args) {object a = 7 If (o__SiteContainer0.p__Site1 = = null) {o__SiteContainer0.p__Site1 = CallSite.Create (Binder.SetMember (CSharpBinderFlags.None, "Error", typeof (Program), new CSharpArgumentInfo [] {CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType, null)}) } o__SiteContainer0.p__Site1.Target (o__SiteContainer0.p__Site1, a, "Error"); a = "Test" If (o__SiteContainer0.p__Site2 = = null) {o__SiteContainer0.p__Site2 = CallSite.Create (Binder.InvokeMember (CSharpBinderFlags.ResultDiscarded, "Run", null, typeof (Program), new CSharpArgumentInfo [] {CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null)}));} o__SiteContainer0.p__Site2.Target (o__SiteContainer0.p__Site2, a) } / / Nested Types [CompilerGenerated] private static class o__SiteContainer0 {/ / Fields public static CallSite paired sites Site1; public static CallSite paired sites 2;}}

You can see from the code that the dynamic object is actually the object object. During compilation, the compiler will generate different CallSite fields for each different method in the class's nested static class SiteContainer. These CallSite will bind the method call information. When the method needs to be actually called, it will call the CallSite in the nested static class SiteContainer generated by the compiler to call the actual method. Here CLR achieves the purpose of Cache by setting the called method as a static variable, that is, if the method is called for the first time, it will create the type, otherwise, it will directly call the previously generated static CallSite type to call the actual method. This can significantly improve the efficiency of a large number of repeated operations. I will test this in detail later.

Use examples

Well, after introducing dynamic, let's discuss the usage scenarios of this new feature. With regard to the examples of the use of dynamic, Anders has already shown a lot of examples in his speech. First of all, I would like to summarize these examples. 1. Interact with javascript in SilverLight. In the video, he not only demonstrates how to call the Javascript method in HTML, but Anders even shows us how to add the Javascipt method directly to the C # code. 2. This example is the interaction between C # and the dynamic language IronPython, in which he demonstrates how we can directly call a Calculate method defined in Python. 3. In addition to these, he also demonstrated the clean and intuitive operation of XML through Dynamic.

Here I would like to add two additional examples of using dynamic, which is actually just an idea I provided, and if you think their implementation is not good, you are welcome to give a different opinion or a more appropriate example.

1. Let generics support operator overloading.

I once mentioned when reviewing generics that .NET generics do not support operators because operators are determined by the compiler and generics are determined by the runtime. So if you want to do + on two generic variables, you won't be able to compile. In fact, when Linq implements the Sum operation, it is also achieved by overloading all the basic data types (e.g.intline long). But with dynamic, this operation will become possible. E.g.

Class MyList {public List Items {get; set;} public T Sum () {dynamic result = default (T); foreach (var temp in Items) {result + = temp;} return result;}}

Here, since we declare Result as a dynamic type, the compiler will not check whether it can perform + operations, but here we have a contract that the types in this summation function should support + operations. Now we can do the following for this class:

MyList l1=new MyList ()... Dynamic a = l1.Sum (); MyList l2=new MyList ()... . A=l2.Sum ()

The other is the XML operation, because all the properties in XML are of type string, but sometimes we need to use their actual types, so dynamic is also useful. Here is an example that I think is good. You can refer to this article:

First we define a dynamic type that inherits DynamicObject.

Code public class DynamicXMLNode: DynamicObject {XElement node; public DynamicXMLNode (XElement node) {this.node = node;} public DynamicXMLNode () {} public DynamicXMLNode (String name) {node = new XElement (name);} public override bool TrySetMember (SetMemberBinder binder, object value) {XElement setNode = node.Element (binder.Name) If (setNode! = null) setNode.SetValue (value); else {if (value.GetType () = = typeof (DynamicXMLNode)) node.Add (new XElement (binder.Name)); else node.Add (new XElement (binder.Name, value));} return true } public override bool TryGetMember (GetMemberBinder binder, out object result) {XElement getNode = node.Element (binder.Name); if (getNode! = null) {result = new DynamicXMLNode (getNode); return true;} else {result = null; return false Once the dynamic XML node class is defined, we can use it like this. Dynamic contact = new DynamicXMLNode ("Contacts"); contact.Name = "Patrick Hines"; contact.Phone = "206555-0144"; contact.Address = new DynamicXMLNode (); contact.Address.Street = "123Main St"; contact.Address.City = "Mercer Island"; contact.Address.State = "WA"; contact.Address.Postal = "68402"

Is it really a seamless connection between XML objects and C # objects?

Deficiency

1. The extension method is not supported. Because whether extension methods can be loaded or not is obtained based on static information such as references to DLL and namespaces, dynamic currently does not support calling extension methods. This also means that Linq cannot be supported by dynamic.

two。 Anonymous methods cannot be supported. An anonymous method (Lamda expression) cannot be passed as a parameter to a dynamic method call. The compiler cannot get the specific type of an anonymous method, so it cannot bind an anonymous method.

Performance?

Many friends consider that a very important disadvantage of dynamic is that it is still object in nature, but CLR achieves the purpose of dynamic invocation through reflection at runtime. Indeed, compared with ordinary method calls, dynamically typed methods do a lot of things the first time they are called. They need to store the information of the call, and then use CallSite.Create () to call the actual method when the method is actually used. Of course, this Create also achieves its goal through reflection.

But does this mean that dynamic is not as good as reflection? The answer is no, in fact, if you look at my code above, you will find that every time a dynamic object calls a method, it will first determine whether the callSite object is empty, and if it is not empty, it can be called directly without re-instantiation, so if your object's method needs to be reused a lot, its performance will not be too poor. Next I will give the code for the test.

My test goal here is to sum a large array. In this test, because the system is XP, I use the performance counter written by the assembly head. You can refer to the modification of the simple performance counter written by Lao Zhao. First, I need to define a structure that supports the + operator (I wanted to use int directly, but I don't know why the addition operator of int cannot be called when testing)

Public struct MyData {public int Value; public MyData (int value) {this.Value = value;} public static MyData operator + (MyData var1,MyData var2) {return new MyData (var1.Value+var2.Value);}}

Then, in order to avoid repeating the process of initializing the list, I simply designed normal method calls, Dynamic mode calls, and reflection calls into a nested class, as shown in the code:

Public class MyTest {public static List Items {get; set;} public MyTest (int count) {Items = new List (count); for (int I = 0; I

< count; i++) { Items.Add(new MyData(1)); } } public void Run() { Console.WriteLine("Compare Times: {0}",Items.Count); CodeTimer.Time("Common", 1, new TestCommon()); CodeTimer.Time("Dynamic", 1, new TestDynamic()); CodeTimer.Time("Reflect", 1, new TestReflect()); } public class TestCommon : IAction { public MyData Result { get; set; } public void Run() { Result = default(MyData); foreach (var d in Items) { Result += d; } } } public class TestDynamic : IAction { public dynamic Result { get; set; } public void Run() { Result = default(dynamic); foreach (dynamic d in Items) { Result += d; } } } public class TestReflect : IAction { public MyData Result { get; set; } public void Run() { Result = default(MyData); Type type = typeof(MyData); MethodInfo m = type.GetMethod("op_Addition", BindingFlags.Public | BindingFlags.Static); foreach (var d in Items) { Result = (MyData)(object)m.Invoke(null, new object[] { Result, d }); } } }} 最后是调用方法: static void main(){ MyTest test = new MyTest(100000); test.Run(); test = new MyTest(1000000); test.Run(); test = new MyTest(10000000); test.Run();} 最后我将给出测试结果,不过我发现每次测试结果数据好像都有所不同,但数据规律大致相似。 普通方法 动态调用 反射 数组大小 100,000 Time Elapsed 9ms 274ms 442ms Time Elapsed (one) 9ms 274ms 442ms CPU time 15,625,000ns 296,875,000ns 484,375,000ns CPU Time (one) 15,625,000ns 296,875,000ns 484,375,000ns Gen 0 0 1 5 Gen 1 0 0 0 Gen 2 0 0 0 数组大小 1,000,000 Time Elapsed 42ms 244ms 3,736ms Time Elapsed (one) 42ms 244ms 3,736ms CPU time 62,500,000ns 281,250,000ns 4,140,625,000ns CPU Time (one) 62,500,000ns 281,250,000ns 4,140,625,000ns Gen 0 0 7 20 Gen 1 0 0 0 Gen 2 0 0 0 数组大小 10,000,000 Time Elapsed 585ms 2,553ms 40,763ms Time Elapsed (one) 585ms 2,553ms 40,763ms CPU time 656,250,000ns 2,796,875,000ns 43,671,875,000ns CPU Time (one) 656,250,000ns 2,796,875,000ns 43,671,875,000ns Gen 0 0 30 205 Gen 1 0 1 4 Gen 2 0 0 0 从表格中我们大致可以看出,直接调用方法最快,并且产生的对象最少。通过反射方式不仅时间往往耗费较多,而且还会生产大量的对象。另外我们发现在1,000,000反而比100,000花费的时间要少,但生成的对象确实增多了。这一点我不太明白,同样的对象通过Cache确实能提高效率,但我不知道为什么多做10倍的加法操作的动态方法调用反而会更快。另外,从图中也可以看出基本上使用dynamic调用方法花费的时间是直接调用的5倍左右,在有些时候,这个性能损失所做的交换也是值得的。 上面的测试数据基本每次都会有所变化,但总体走势是基本不变的,那就是花费时间common>

Dynamic > Reflect. So we can think that although dynamic does have a performance loss, sometimes it can be considered if your system does need to dynamically generate objects or dynamically call methods, especially if your system needs to use reflection and this type of operation will be repeated many times.

Postscript

There are not many use cases for the dynamic keyword, and the debate about whether it is good or not has not stopped. In fact, up to now, there are many people who are skeptical and opposed to dynamic. They think that the performance of dynamic is not good, and the arrival of dynamic makes the compiler's autocomplete function gone, and at the same time, it is unable to complete the check of member calls at compile time, which will greatly increase the error probability of ordinary programmers.

There is no denying that improper use of dynamic does lead to a much higher chance of programmers making mistakes. However, as Spider-Man said, the greater the ability, the greater the responsibility. In fact, Microsoft's introduction of dynamic also gives C # programmers more powerful capabilities than ever before, but this powerful ability can also lead to errors if not used properly. But can we say that this ability is ugly or bad? I think there is no difference in ability between good and bad. It depends on users, such as nuclear power. By the same token, smart programmers can use a feature elegantly and efficiently, while stupid programmers do the opposite. Secondly, we can try our best to avoid the possible problems of these dynamic languages in other ways. First of all, we can get the maximum guarantee through unit testing to check the validity of type or member calls. Unit testing is necessary for a large and robust program. Second, we do lack smart tips after using dynamic, but I don't advocate using dynamic everywhere (in fact, that's wrong, because it will significantly reduce the efficiency of the program). What I mean is that you only use dynamic when you really need it, which is why this keyword exists. There are not many places that need to use dynamic, and we can understand what we are going to do with it in these places. With these two guarantees, I believe the inconvenience caused by dynamic will not be so obvious.

Finally, dynamic is just one more choice Microsoft gives us programmers, and if you don't like it, you can certainly avoid using it in many situations, such as type conversion, reflection, and so on. With or without it, Microsoft left the choice to us programmers. In addition, you can also watch more introduction to Dynamic from C # Compiler Team: C # 4.0 Dynamic with Chris Burrows and Sam Ng

Note:

Note 1: The future of C #, Anders Hejlsberg, http://channel9.msdn.com/pdc2008/TL16/

Note 2: Visual C# Express 2010 download address: http://www.microsoft.com/express/future/default.aspx

Reference:

New features in C# 4.0

Result Screenshot:

Machine information:

Thinkpad X200 7654: Intel Core2 Duo CPU p8400 2.25GHz; virtual machine: VMWare 6.5; virtual memory: 1G; virtual machine operating system: Windows XP; compiler version: Visual C # Express 2010 Beta2.

This is the end of the article on "what is the new feature Dynamic in .NET 4.0". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report