.NET 4.0の新機能:C#4.0

Visual Studio 2010ベータ1のリリース後-最初に把握する必要があるのは、新しいC#4.0を提供することです(これが私の主要なプログラミング言語であるため-私にとっては重要です)。 最初にお勧めするのは、 ここからダウンロードできるC#4.0の例です (このトピックの基礎となるC#4.0の新機能のドキュメントもあります)。 .Net Framework 4.0 beta 1のドキュメントは、MSDNで表示できます。 .NETの新しいバージョンでの私の小さな経験が続きます。

1.動的言語ランタイム

最初に、DLRアーキテクチャを示す次の図を見てください。

まさに! .netでは、 IronRubyIronPythonなどのスクリプト言語も使用できます。 私はそれを使うとは思わないが、エキゾチックな愛好家へのリンクを提供する:さらに、必要に応じて、おそらく.NET用の独自の動的言語を作成できるDLRソースが提供されます。

したがって、DLRにはExpression Treeが含まれています。これは、メソッド呼び出しまたはツリー形式のバイナリ操作の単なる表現であり、その機能は次の例で見ることができます。
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 .
この例では、最初にラムダ式num => num <5について説明し、次に式ツリーのオブジェクトを使用してこの式を解析します。

DLRのCall Siteキャッシングは、私が理解しているように、動的オブジェクトのメソッドまたは動的オブジェクトの操作への呼び出しの動的表現です。 DLRは、オブジェクトの特性(オブジェクトの種類に関する)、および操作に関するキャッシュを作成します。この操作が既に以前に実行されている場合、DLRはすべての必要な情報をキャッシュから取得します(そのようなもの)。

そして、DLRの最後のものは、クラス、インターフェイスのセットです: IDynamicMetaObjectProvider、DynamicMetaObject、DynamicObjectおよびExpandoObject。 これがどのように役立つか、そしてなぜこのDLRが必要なのか、もう一度例を見てみましょう。
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 .
驚くべきことに、このコードはコンパイルして実行されます。 それはすべて、魔法の単語dynamicに関するもので、名前によってプロパティやメソッドを呼び出したり、オブジェクトを任意の型にキャストしたりすることができます。 ランタイム(コード実行)エラーが発生します。エラー1:メソッドが見つからなかったこと、エラー2:そのdoubleをintにキャストできません。 それらを修正してみましょう。最初のエラーを修正するには、System.Dynamic.DynamicObject型からTest1クラスを継承し、メソッドの1つをオーバーロードします。2番目を修正するには、型変換を明示的に指定します。
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 .
これでコードが機能します。 変数strは、値「Test1 is dynamic object!」を取得します 、およびi7です。

もちろん、 DynamicObjectクラスから継承する必要はなく、 IDynamicMetaObjectProviderインターフェイスから継承することもできますが、 DynamicMetaObject GetMetaObject(Expressionパラメーター)メソッドを自分で実装する必要があり、 さらに DynamicMetaObjectから継承した型を実装する必要があります。採用する。

2.メソッドの名前付きおよびオプションのパラメーター

これは非常にシンプルな機能であり、すでに多くの場所で言及されています; ここで著者syntezzzによってよく説明されています 。 数語の場合、これはメソッドパラメータのデフォルト値を設定する機能、およびメソッドが呼び出されたときに名前でパラメータ値を設定する機能です。 一般に、例はよりよい説明です:

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 .
メソッドパラメーターの名前変更により、名前による値の設定を使用した場合、コードがコンパイルされない可能性があるため、注意する必要があります。 デフォルト値に満足しており、名前付きパラメーターの機能を使用しないようにしています。
さらに、 Test1クラスにvoidメソッド(int a)メソッド がまだある場合、 o.Method(1)が呼び出されると、デフォルト値を持つ例のメソッドではなく、呼び出されます。

3. COM相互運用機能

DLRはまた、COM相互運用機能に新しい機会を提供しました。現在、COMオブジェクトを動的(より正確には、ほとんどが動的型)として定義し、メソッドまたはプロパティを呼び出すためにオブジェクトを特定の型に常にキャストすることはできません。
excel.Cells[1, 1].Value = "Hello" ;
//
((Excel.Range)excel.Cells[1, 1]).Value2 = "Hello" ;

* This source code was highlighted with Source Code Highlighter .
この例は、ドキュメント「C#4.0の新しい未来」から引用したものです。一方で、オブジェクトをキャストしてそのプロパティまたはメソッドを呼び出すために必要なタイプを見つける必要がなくても、IntelliSenseが失われるのは便利です。

4.ジェネリックの新機能

現在、機能が強化され、新しい機能が追加されています。 ジェネリック型を定義する前 、インターフェイスとデリゲートを書き込みおよび書き込みできるようになりました 。なぜこれがもう少し進んでいるのか、最初に例を見てみましょう。
ジェネリックを使用する場合、次のようなことをしたいことがよくあります。
IList< string > strings = new List < string >();
IList< object > objects = strings;

* This source code was highlighted with Source Code Highlighter .
しかし、できません。 次に書くことができるから:
objects[0] = 5;
string s = strings[0];

* This source code was highlighted with Source Code Highlighter .
つまり、最初は文字列のリストがあり、それをオブジェクトのリストとして指定し、それをオブジェクトと同様に操作し、その中に他のオブジェクトをインストールしますが、リストはまだ文字列のリストです。
しかし、考えてみると、リストが読み取り専用の場合、次のC#4.0コードが機能するため、何も壊せず、ロジックがそこにあることがわかります。
IEnumerable < object > objects = strings;

* This source code was highlighted with Source Code Highlighter .
この機能は、linqの操作に非常に役立ちます。1つのタイプのオブジェクトを返す問題がよくありますが、別のタイプ(ベース)のリストを取得する必要があります。
それで、どうしてこれが可能になったのでしょう。 まず、 outという単語を検討ます。 現在、 IEnumerable <T>インターフェイスはIEnumerable <out T>として宣言されています。outは、型Tが値を返すためにのみ使用できることを意味します。そうでない場合、コンパイラはさらに、 IEnumerable <A>インターフェイスIEnumerable <B>もあります。ABにキャストできる場合、単純な例ではIEnumerable <string>があり、 IEnumerable <object>があります。 以下に例を示します。
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 .
に別の単語があります。 また、汎用デリゲートとインターフェイスを記述するためにも使用できます。 outという単語と同じ意味を持ちますが、この場合のみ、記述されたタイプはパラメーターの受け渡しでのみ使用できます。以下に例を示します。
public interface IComparer< in T>
{
public int Compare(T left, T right);
}

* This source code was highlighted with Source Code Highlighter .
つまり、この場合、 IComparer <object>IComparer <string>と見なすことができるのは、object型のオブジェクトを比較できる場合、 stringも可能だからです。

先ほど言ったように、 outinの言葉はインターフェースに適用できます。例えば:
public delegate TResult Func< in TArg, out TResult>(TArg arg);

* This source code was highlighted with Source Code Highlighter .
おわりに

また、.NET 4.0では、 遅延初期化など、多くの革新が登場しました。オブジェクトのメモリは、実際に必要になったときに割り当てられます。 BigIntegerなどの新しいタイプが登場しました-現在、学生は実験室での作業のために大きな数で作業するためにクラスを書く必要がありません;)、 SortedSet <T> -クラスは、挿入、削除、検索。 一般に、まだ学ぶべきことがあります。

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


All Articles