Lập trình .net 4.0 và visual studio 2010 part 7 pps

5 374 0
Lập trình .net 4.0 và visual studio 2010 part 7 pps

Đang tải... (xem toàn văn)

Thông tin tài liệu

CHAPTER 3  LANGUAGE AND DYNAMIC CHANGES 51 Further Reading Variance is a difficult subject, so for more information please refer to the following blogs and book: • http://blogs.msdn.com/charlie/archive/2008/10/28/linq-farm-covariance-and- contravariance-in-visual-studio-2010.aspx • http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/ default.aspx • Skeet, Jon. (2008) C# in depth. Manning Publications. Dynamic Enhancements The new dynamic functionality in .NET 4.0 allows us to work with types not known at compile time in an intuitive and easy to read way. Many of you may be wondering what can the dynamic changes do for you. The dynamic changes allow us to do the following: • Write more readable code with fewer casting operations. • Create new languages to utilize the .NET Framework, such as IronPython and IronRuby. Additionally, .NET’s dynamic architecture allows these languages to automatically benefit from future framework advances.Utilize other dynamic languages and their libraries. • Utilize other dynamic languages and their libraries from C# and VB.NET. • Introduce customization/scripting and debugging/querying functionality within our applications. • Work with COM objects more easily. Microsoft Office COM is going to be around for some time whether you like it or not. • Many other cool uses we haven’t thought of yet. Can’t We Do This Kind of Thing Already in .NET? .NET has a number of classes and methods for working with types not known at compile time, such as reflection and expression trees. However, if you have spent much time with these technologies, you will known that they can make for some clunky and difficult to read code. As I will show you, the dynamic enhancements can make your life much easier. Before we look at how to use the dynamic enhancements, we need to understand the difference between statically and dynamically typed languages. Static Languages In a statically typed language, such as C# or C, the compiler checks you are using types correctly at compile time. Compilation will fail, for example, if you assign a string to an integer or misspell a variable name. Statically typed languages can catch simple syntax errors and typos during development and as the compiler knows the types it will be working with static languages generally run quicker then dynamic languages (next) as optimizations can be performed on code. CHAPTER 3  LANGUAGE AND DYNAMIC CHANGES 52 Dynamic Languages In contrast, dynamic languages, such as JavaScript, Python, Lisp, and Ruby, do not perform type checks on code until runtime. This can be a big advantage if you don’t know the type of object you will be working with at compile time. These features can also make it possible to perform some interesting code tricks and reduce tedious casting operations if the language can work out how to use the type. Some developers feel dynamic languages can help them develop and prototype applications much quicker, and can be particularly suitable for testing and prototyping applications. The main disadvantage of working with dynamic languages is they of course lack compile time checks and generally have inferior performance when compared to static languages. When working with dynamic languages, simple syntax errors and typos can stop your code working. I think anyone that has done any web development has spent much time tracking down such an error in JavaScript with its very helpful “object not set to an instance” message. Dynamic Dangers When working with dynamic types and the Dynamic Language Runtime (DLR) there are three considerations you should bear in mind. • IDE support is limited • Generally, performance is poor (although precompilation is sometimes possible), especially on the first call to a method where the DLR has not yet cached a method call. • Using the DLR unnecessarily is not big or clever (more complexity = bad). I’ll cover the DLR in detail later in this chapter. Type Dynamic .NET 4.0 introduces a new type dynamic that allows you to tell the compiler to resolve a variable’s type at runtime. Somewhat paradoxically the keyword dynamic statically types an object as dynamic. To declare an object as dynamic, prefix the variable name with the type dynamic: dynamic myDynamic="Something"; Console.WriteLine(myDynamic.GetType().Name); Console.ReadKey(); What type will be output on the second line? Dynamic, object? For those of you who said String you are correct (now stop looking so smug); I will explain why this is shortly. Is dynamic the Same as Var? No, dynamic is very different. When the var keyword is used the compiler infers the type of value you are using and writes the appropriate code for you when you compile the application. Variables declared using var benefit from type checks, Intellisense, and offer better performance than their dynamic equivalent. Types declared as dynamic are evaluated at run time and do not have these benefits. CHAPTER 3  LANGUAGE AND DYNAMIC CHANGES 53 Why Type Variables as Dynamic? One advantage is that it can avoid some tedious casting and Reflection code. For example, let’s say we want to create an instance of a type using a string and call a method on it at runtime. In our example we will create a StringBuilder instance and call the Append method on it using Reflection: object UsingReflection = Activator.CreateInstance(Type.GetType("System.Text.StringBuilder")); Type ObjectType = UsingReflection.GetType(); //Append has many overloads so we need to tell reflection which type we will use Type[] TypeArray = new Type[1]; TypeArray.SetValue(typeof(string), 0); var ObjectMethodInfo=ObjectType.GetMethod("Append", TypeArray); ObjectMethodInfo.Invoke(UsingReflection, new object[] { "alex" }); Console.WriteLine( ObjectType.GetMethod("ToString", new Type[0]).Invoke(UsingReflection, null) ); Console.ReadKey(); By using dynamic, however, we can make this simpler and more readable (and I know which bit of code I could remember): dynamic usingDynamic = Activator.CreateInstance(Type.GetType("System.Text.StringBuilder")); usingDynamic.Append("Hello"); Console.WriteLine(UsingDynamic.ToString()); Console.ReadKey();  NOTE Technically you could do something similar in VB.NET by declaring UsingDynamic as object, so arguably VB.NET could be considered to contain dynamic functionality already. Consider using dynamic types in the following situations: • When working with COM, dynamic types allow a more concise syntax (we saw this earlier). Let the DLR do the work figuring out how to bind your method and property calls. • When interacting with a dynamic language such as IronPython. • When working with objects that have changing structures, such as HTML or XML documents (we will look at this shortly). System.Dynamic.ExpandoObject ExpandoObject is a strange new beast in the .NET Framework that allows you to add and remove properties, methods, and events at runtime. The following example demonstrates how to add two new values and a method: CHAPTER 3  LANGUAGE AND DYNAMIC CHANGES 54 using System.Dynamic dynamic MyExpando = new ExpandoObject(); MyExpando.Value1 = "new value 1"; MyExpando.Value2 = "new value 2"; MyExpando.DoSomething = new Action(() => Console.WriteLine("DoSomething called")); Console.WriteLine(MyExpando.Value1); MyExpando.DoSomething(); Console.ReadKey(); ExpandoObject could be used for wrapping data and making it easier to work with and is included for interoperability with dynamic languages that support this concept. System.Dynamic.DynamicObject .NET 4.0 introduces a new class called DynamicObject that allows the definition of runtime behavior, offering a much greater level of control than ExpandoObject. It is important to note that DynamicObject is never instantiated directly but must be inherited from. DynamicObject again is great for wrapping data and making it easier to work with, but offers a much finer level of control than ExpandoObject. If you just need to define parameters at runtime you will probably be adequately served by ExpandoObject (above) however DynamicObject allows you full control over various operations performed. The following example shows how to query an XML document using properties to create more readable code: using System.Dynamic; using System.Xml.Linq; class Program { static void Main(string[] args) { dynamic easierXML = new EasierXML(@"<test><node1>Alpha</node1><node2>Beta</node2></test>"); Console.WriteLine(easierXML.node1); Console.WriteLine(easierXML.node2); Console.ReadKey(); } public class EasierXML : DynamicObject { private XDocument _xml = new XDocument(); public EasierXML(string Xml) { this._xml = XDocument.Parse(Xml); } CHAPTER 3  LANGUAGE AND DYNAMIC CHANGES 55 public override bool TryGetMember(GetMemberBinder binder, out object result) { string nodeName = binder.Name; result = _xml.Element("test").Element(nodeName).Value; return true; } } } In this example, the TryGetMember() method intercepts the call to .node1 and .node2, thus allowing us to query the XML document and return the individual nodes. IDynamicMetaObjectProvider IDynamicMetaObjectProvider is an important interface in the dynamic world that represents an object that has operations bound at runtime. Both ExpandoObject and DynamicObject implement this interface. You can use this interface to add dynamic functionality to your own classes. IDynamicMetaObjectProvider requires you to implement GetMetaObject(),(), which resolves binding operations (for example, method or property invocation on your object). Dynamic Limitations When working with dynamic objects, there are a number of constraints you should be aware of: • All methods and properties in classes have to be declared public to be dynamically accessible. • You cannot use the DLR to create classes in C# or VB.NET. Apparently, the DLR does allow you to create classes, but this cannot be expressed using C# or VB.NET. • Dynamic objects cannot be passed as arguments to other functions. • Extension methods cannot be called on a dynamic object and a dynamic object cannot be passed into extension objects. Annoyingly, these restrictions stop you calling an extension method on a dynamic object. Dynamic IL You may be wondering what code the C# compiler generates when you use the dynamic keyword. Let’s take a look at the IL that is generated using ILDASM for a simple console application that declares and initializes a string: string d; d = "What do I look like in IL"; . http://blogs.msdn.com/charlie/archive/ 200 8/ 10/ 28/linq-farm-covariance-and- contravariance-in -visual- studio- 201 0.aspx • http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/ default.aspx • Skeet, Jon. ( 200 8). http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/ default.aspx • Skeet, Jon. ( 200 8) C# in depth. Manning Publications. Dynamic Enhancements The new dynamic functionality in .NET 4. 0 allows us to work with types not known at compile. (more complexity = bad). I’ll cover the DLR in detail later in this chapter. Type Dynamic .NET 4. 0 introduces a new type dynamic that allows you to tell the compiler to resolve a variable’s

Ngày đăng: 01/07/2014, 21:20

Tài liệu cùng người dùng

Tài liệu liên quan