📜 ⬆️ ⬇️

New .NET 4.0 Features: C # 4.0

After the release of Visual Studio 2010 beta 1 - the first thing you need to figure out what gives us new C # 4.0 (since this is my main programming language - for me it is important). First of all I should recommend you examples of C # 4.0, which can be downloaded from here (there is also a document New Features in C # 4.0, which served as the basis for this topic). Documentation on the .Net Framework 4.0 beta 1 can be viewed in MSDN . My little experience of acquaintance with the new version of .NET will follow on.

1. Dynamic Language Runtime

Initially, take a look at the following diagram, which illustrates the DLR architecture:

Exactly! Now in .net you can also use scripting languages ​​such as IronRuby and IronPython . I do not think that I will use it, but I give links to exotic lovers:Moreover, the DLR source code is provided, with which you can probably create your own dynamic language for .NET if you need it
.
So DLR includes Expression Trees , which are simply a representation of method calls or binary operations in the form of a tree, their functionality can be seen in the following example:
Expression<Func< int , bool >> exprTree = num => num < 5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;
Console .WriteLine( "Decomposed expression: {0} => {1} {2} {3}" ,
param.Name, left.Name, operation.NodeType, right.Value);


* This source code was highlighted with Source Code Highlighter .
In this example, we first describe the lambda expression num => num <5 , and then use the objects from the Expression Trees to parse the expression.

Call Site caching in DLR is, as I understand it, and there is a dynamic representation of calls to methods of dynamic objects or operations on dynamic objects. DLR caches the characteristics of the objects (about the types of objects), as well as about the operation, and if this operation has already been performed before, then all the necessary information will be received from the cache (this is how it is).
')
And the last thing in DLR is a set of classes, interfaces: IDynamicMetaObjectProvider, DynamicMetaObject, DynamicObject and ExpandoObject. Let's look again at an example of how it can be useful to us, and why we need this DLR at all:
class Test1
{
}

static void Main( string [] args)
{
dynamic t = new Test1();
string str = t.Hello(); // Error 1

dynamic d = 7.0;
int i = d; // Error 2
}


* This source code was highlighted with Source Code Highlighter .
Surprisingly, this code will compile and run. It's all about the magic word dynamic , it allows us to call any properties or methods by name, and also to cast an object to any type. During Runtime (code execution) errors will crash, Error 1: that the method was not found, Error 2: that it is impossible to result in a double to int. Let's try to fix them: to fix the first error, our Test1 class is inherited from the System.Dynamic.DynamicObject type and overload one of the methods, to fix the second one just explicitly specify the type conversion:
class Test1 : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object [] args, out object result)
{
if (binder.Name == "Hello" )
{
result = "Test1 is Dynamic Object!" ;
return true ;
}
return base .TryInvokeMember(binder, args, out result);
}
}

static void Main( string [] args)
{
dynamic t = new Test1();
string str = t.Hello();

dynamic d = 7.0;
int i = ( int ) d;
}


* This source code was highlighted with Source Code Highlighter .
Now our code will work. The variable str get the value "Test1 is a dynamic object!" , and i value is 7 .

Of course, you do not need to inherit from the DynamicObject class, you can also inherit from the IDynamicMetaObjectProvider interface, but then you will need to implement the DynamicMetaObject GetMetaObject (Expression parameter) method yourself , and moreover you will have to implement your own type inherited from DynamicMetaObject , well, in any case, there is a way to do it. to adopt.

2. Named and optional parameters in methods

This is a fairly simple functionality and has already been specified in many places, it is well described by the author of syntezzz here . If in a couple of words, it is an opportunity to set default values ​​for method parameters, as well as the ability to set a parameter value by name when calling a method. In general, an example would be the best explanation:

class Test1
{
public void Method( int a = 0, string b = "Hello" , bool c = true )
{
Console .WriteLine( "{0}, {1}, {2}" , a, b, c);
}
}

static void Main( string [] args)
{
Test1 o = new Test1();
//
o.Method(1, "Hello" , true );
//
o.Method(b: "hello" , c: true , a: 1);
//
// ( )
o.Method();
//
o.Method(1, "Hello" );
//
o.Method(c: false );
}


* This source code was highlighted with Source Code Highlighter .
Now, because of the renaming of a parameter of a method, the code may not compile if someone has used the setting value by name, so you need to be careful. I am happy with default values, and I will try not to use the functionality of the named parameters.
In addition, I want to say that if all the same class Test1 has a method void Method (int a) , then when calling o.Method (1) , it is he who will be called, and not the method from the example with default values.

3. Features for COM Interop

DLR also gave new opportunities for COM Interop, now it is possible to define COM objects as dynamic (more precisely, they are already mostly dynamic types) and not to constantly get objects to certain types for calling methods or properties.
excel.Cells[1, 1].Value = "Hello" ;
//
((Excel.Range)excel.Cells[1, 1]).Value2 = "Hello" ;

* This source code was highlighted with Source Code Highlighter .
This example is taken from the New Futures in C # 4.0 document. On the one hand, it's nice that now you don’t have to suffer and find what type you need to bring an object to call its property or method, but on the other hand, IntelliSense is lost.

4. New generic

Now enriched and generic new functionality. Now it is possible for interfaces and delegates to write out and in before defining generic types, why this is a little further, but first consider an example.
When working with generic, you often want to do something like this:
IList< string > strings = new List < string >();
IList< object > objects = strings;

* This source code was highlighted with Source Code Highlighter .
But it is impossible. Because you can write next:
objects[0] = 5;
string s = strings[0];

* This source code was highlighted with Source Code Highlighter .
That is, initially we had a list of strings, then we designated it as a list of objects, and we want to work with it as objects, setting any other object to it, although the list is still a list of strings.
But, if you think about it, you can imagine that if the list were read-only, we would not be able to break anything, and there the logic would be clear, because the following code in C # 4.0 would work:
IEnumerable < object > objects = strings;

* This source code was highlighted with Source Code Highlighter .
This functionality will bring great utility in working with linq, there are often problems that return objects of one type, and you need to get a list of another type (base).
So, how is it possible. First consider the word out . Now the IEnumerable <T> interface is declared as IEnumerable <out T> , where out indicates that type T can only be used to return values, otherwise the compiler will swear, well, moreover, it gives us that IEnumerable interface <A> there is also an IEnumerable <B> , if A has the ability to cast a type to B , if by a simple example, then IEnumerable <string> , there is now an IEnumerable <object> . Here is an example:
public interface IEnumerable < out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator< out T> : IEnumerator
{
bool MoveNext();
T Current { get ; }
}

* This source code was highlighted with Source Code Highlighter .
There is another word in . It can also be used in the description of generic delegates and interfaces. It carries the same meaning as the word out , only in this case the described type can be used only in the transfer of parameters, here is an example:
public interface IComparer< in T>
{
public int Compare(T left, T right);
}

* This source code was highlighted with Source Code Highlighter .
That is, in this case, if IComparer <object> can be considered as IComparer <string> , because if it can compare objects of type object , then string can also.

Just as I said, the words out and in can be applied to interfaces as well, for example:
public delegate TResult Func< in TArg, out TResult>(TArg arg);

* This source code was highlighted with Source Code Highlighter .
Conclusion

Also in .NET 4.0 there are a lot of innovations, such as Lazy Initialiation - memory is allocated for an object when it really becomes necessary. There are new types, such as BigInteger - now, for laboratory work, students do not need to write their classes for working with large numbers;), SortedSet <T> - a class is an independent balanced tree that stores data in sorted order after insertion, deletion and search. In general, there is still something to learn.

Source: https://habr.com/ru/post/60206/


All Articles