この記事は次から転送されます:https : //www.cnblogs.com/yubinfeng/p/4570688.html
最後の2つのセクションでは、.net配列、コレクション、ジェネリックを紹介しました。配列は以前のプログラミング言語から拡張された参照型であり、長さを事前に定義することにより記憶領域が割り当てられると述べました。このコレクションは、初期の.Netバージョンでのデータセット取得の利便性を考慮して設計されています。これは配列よりも優れています。取得の利便性に加えて、事前にサイズを定義しなくても、使用中にストレージ領域を自動的に割り当てることができます。ただし、コレクションには、安全でない型と頻繁なボックス化およびボックス化解除操作によって引き起こされるパフォーマンスの問題があります。Genericsは.net 2.0の後に設計され、コレクションの欠陥を解決し、インスタンスの呼び出し段階で型を宣言する方法を採用して、セキュリティの問題と効率の問題を解決しています。
.net 3.5以降のバージョンの開発に伴い、マイクロソフトはLINQを設計して、検索をより便利にし、開発をより効率的にしました。
1. LINQのコンセプト
LINQ、Language Integrated Queryは、c#およびVisual Basic言語の拡張機能のセットです。それはあなたが書くことができますデータベースを同じ方法で動作するデータメモリを照会するC#またはVisual Basicコードを。
上記は百度百科事典の定義です。
英語の名前の説明から、これが開発者がデータベースのクエリのようにメモリデータを取得できるソリューションであることがわかります。
2. LINQを学ぶ前に、次の知識ポイントを習得する必要があります
少し見えますが、それらはすべてLINQの学習の基本です。LINQはSQLステートメントのようにメモリデータを操作することです。SQLを学習するには、テーブル、フィールド、ビューの基本概念を習得する必要があります。LINQも同じです。
2.1暗黙の型
変数を定義する前に、型を指定する必要があり、foreachトラバーサルでは型も指定しました。暗黙の型の出現により、この作業を行う必要がなくなり、javasciptなどの弱く型付けされた言語のようなvar定義を使用するだけで十分です。しかし、.NETは弱く型付けされた言語ではなく、暗黙の型の定義は次のように記述されます。
var i = 1; var b = "xyz"; var obj = new MyObj();
上記の暗黙の型は次と同等です
int i = 1; 文字列b =” xyz”; MyObj obj = new MyObj();
暗黙の型に関する注意事項:
A.暗黙の型では、varを使用して、コーディングで任意の型の変数を定義できます。
B.暗黙的な型はプログラムのパフォーマンスに影響を与えません。.NETはコンパイル時に特定のデータ型に変換するのに役立ちます。したがって、暗黙的な型を宣言するときに値を割り当てる必要があります。そうでない場合、.NETはエラーに変換された型を判断できません。
C.暗黙的に型指定されたvarを使用すると、開発時間を大幅に節約できます。変数を定義するとき、型は2回失われる必要があり、varはワンクリックで実行されます。varを使用して、foreachトラバーサル中にループ変数のタイプを書き込むこともできます。
2.2匿名型
新しいオブジェクト、その要素と型は匿名で宣言できますが、匿名で宣言できます。次のように:
//匿名类型 var obj = new {str = "abc"、Guid.Empty、myArray = new int [] {1、2、3}}; Console.WriteLine(obj.str); Console.WriteLine(obj.Empty); Console.WriteLine(obj.myArray [0]); Console.ReadLine();
結果は次のとおりです。
新しいオブジェクトが表示されたら、オブジェクトのプロパティを自動的に定義し、これらのプロパティに値を割り当てます。オブジェクトのプロパティを匿名オブジェクトにコピーする場合、指定したプロパティの名前を表示する必要はありません。以下に示すように、匿名オブジェクトに「コピー」します。
obj.Emptyプロパティ名は自動的に作成されます。
変数objを監視すると、objの型がAnonymous Type型であることがわかります。
匿名オブジェクトを作成するメソッドの外でオブジェクトのプロパティにアクセスしないでください。
この機能は、Webサイト開発でJSONオブジェクトをシリアライズおよびデシリアライズするのに役立ちます。
2.3自動プロパティ
「リファクタリング」セクションでは、属性のリファクタリングについて説明したことを思い出してください。以下に示すように、フィールド名に対してvs.netによって提供される「カプセル化フィールド」を使用して、対応する属性を生成するだけで済みます。
(図1)
(図2)
(図3)
.net 3.0以降、コードはより簡単に記述できます。コードは次のとおりです。
//自動属性 クラスFlower { public string Leaf {get; set;} public string Name {get; set;} }
もちろん、リファクタリングは.netの補助機能にすぎません。自動属性のフレンドの場合、この書き込みの効率については確実に心配します。これは保証されます。var暗黙型と同様に、.netは完全な書き込みに役立ちます、パフォーマンスの問題なし。
2.4イニシャライザ
オブジェクトの初期化のために、次の2つのオブジェクトがあるとします。
//初始化器 class Flower { public string Leaf {get; set;} public string Name {get; set;} } class Bear { public Bear(string name){} public string Name {get; セットする; } public double Weight {get; セットする; } }
3.0より前のバージョンでは、一般的に次のようになります。
// イニシエーター Flower flower = new Flower(); flower.Leaf = "leaf"; flower.Name = "cotton";
3.0以降のバージョンでは、次のように記述できます。
// .net 3.0の後のオブジェクトの初期化は次のように記述できます Flower flower2 = new Flower(){Name = "桃花"、Leaf = "桃叶"}; //パラメータオブジェクトでコンストラクタを初期化 Bear bear = new Bear( "polar bear" ){Name = "熊熊"、Weight = 300}; //初期化変数 配列を設定=新しいリスト<文字>(){'a'、 'b'、 'c'、 'd'、 'e'、 'f '};
文章がはるかにシンプルで優れていることがわかります。特に、ジェネリックコレクションへの割り当ては非常に簡潔で明確です。
2.5匿名メソッド
匿名メソッドとは、メソッドを委任するときに、デリゲートステートメントでメソッドを記述できることを意味します。簡単に言えば、メソッドを個別に記述する必要はありません。これについて説明する前に、最初は委任を紹介したかったのですが、次のセクションでは、委任の説明に焦点を当てます。ここでは、匿名メソッドのみを理解する必要があります。例を見てみましょう:
1 //デリゲート関数 2 Func <int、int、string> func1 = Adds; 3 //匿名メソッド 4 Func <int、int、string> func2 = 5デリゲート(int a、int b) 6 { 7 return a + "+ "+ b +"はいくつですか? "+ Environment.NewLine +(a + b).ToString(); 8}; 9 //ラムダ式 10 Func <int、int、string> func3 = 11(a、b)= > {return a + "+" + b + "What is equal to ??" + Environment.NewLine +(a + b).ToString();}; 12 13 // Funcデリゲートを呼び出す 14 string sum = func2(45、36 ) ; 15 16 Console.WriteLine(合計); 17 Console.ReadLine();
//デリゲートメソッドの 静的文字列Adds(int a、int b) { return a + "+" + b + "What is equal to?" + Environment.NewLine +(a + b).ToString(); }
匿名メソッドを使用すると、コンテキスト内の変数にアクセスできますが、メソッド自体がそれほど長くない場合は、軽量な書き込みが非常に実用的です。
これは、次のセクションの委託で指定されています。友達がここで理解していなくてもかまいません。
2.6拡張メソッド
1)拡張メソッドは、静的メソッドとして定義された静的クラスで宣言され、その最初のパラメーターは、拡張する型を示すthisキーワードで識別する必要があります。
2)拡張メソッドは、最初はメソッドを提供しなかったクラスにメソッドを書き込むことができます。複数のクラスが同じ実装コードを使用できるように、インターフェイスを実装する任意のクラスにメソッドを追加することもできます。(LINQでは、System.Linq.Queryable.csおよびSystem.Linq.Enumerable.csがインターフェイスに拡張メソッドを追加します)
3)拡張メソッドは静的メソッドとして定義されていますが、呼び出されるときに静的メソッドを定義するクラスの名前を提供する必要はありません。対応する名前空間を導入するだけでよく、アクセスメソッドはインスタンスメソッドと同じです。
4)拡張メソッドは、それが拡張するタイプのプライベートメンバーにアクセスできません。
例:
public static IEnumerable <TSource> MyWhere <TSource>( this IEnumerable <TSource> source、Func <TSource、bool> predicate) { foreach(TSource item in source) { if(predicate(item)) yield return item; } }
拡張メソッドの力を見てみましょう。型に動作を追加するために、継承されたメソッドを使用する必要はありません。次のように書くこともできます。
var a = "aaa"; a.PrintString(); Console.ReadKey();
しかし、上記のコードを通じて、PrintStringメソッドは文字列型に「拡張」されています。
(1)前提条件
<1>拡張メソッドは、ネストされていない、ジェネリックでない静的クラスで定義する必要があります
<2>拡張メソッドは静的メソッドでなければなりません
<3>拡張メソッドには少なくとも1つのパラメータが必要です
<4>最初のパラメータには、このキーワードを前に付ける必要があります
<5>最初のパラメーターに他の修飾子(refやoutなど)を含めることはできません
<6>最初のパラメーターをポインター型にすることはできません
(2)注意事項
<1>上記のいくつかの機能と同様に、拡張メソッドはコンパイラーの作業を増やすだけで、パフォーマンスには影響しません(継承によって型に機能を追加するとパフォーマンスに影響します)
<2>元のクラスに拡張メソッドと同じ(少なくとも同じ)メソッドがある場合、拡張メソッドアワードは呼び出されず、コンパイラーはプロンプトを表示しません。
<3>拡張メソッドが強力すぎるため、アーキテクチャ、モード、読みやすさなどに影響します...
2.7イテレーター
(1)使用
コレクション型のforeachコードブロックを記述するたびに、イテレータを使用しています
これらのコレクション型はIEnumerableインターフェイスを実装します
GetEnumeratorメソッドがあります。
しかし、これは配列型には当てはまりません
コンパイラーは配列タイプにforeachコードブロックを配置します
コードブロックに置き換えられました。
リストの型シグネチャを見てみましょう:
パブリッククラスList <T>:IList <T>、ICollection <T>、IEnumerable <T>、IList、ICollection、IEnumerable
IEnumerableインターフェイス。1つのメソッドのみが定義されています。
IEnumerator <T> GetEnumerator();
(2 )イテレータの利点:
膨大なコレクションをトラバースする必要があるとします
セット内の特定の要素が条件を満たしている限り
タスクを完了しました
この膨大なコレクションをメモリにロードする必要があると思いますか?
もちろんそうではありません(C#3.0以降ではありません)。
このコードを見てみましょう:
static IEnumerable <int> GetIterator() { Console.WriteLine( "Iterator returned 1"); yield return 1; Console.WriteLine( "Iterator returned 2"); yield return 2; Console.WriteLine( "Iterator Returned 3 "); 利回りreturn 3; }
foreach(var i in GetIterator()) { if(i == 2) { break; } Console.WriteLine(i); } Console.ReadKey();
出力は次のとおりです。
イテレータは1を返します1 1 イテレータは2を返します
あなたは見ることができます:
イテレータが2を返すと、foreachは終了します
そして、「イテレータが3を返しました」を出力しませんでした
つまり、次の作業は行われません。
(3)利回りキーワード
MSDNの説明は次のとおりです。
イテレータブロックで使用して、列挙子オブジェクトに値を提供したり、反復の終了を通知したりします。
つまり、イテレータを生成するときに、反復ロジックをいつ終了するかを決定できます。
上記のコードは、次の形式に変更できます。
static IEnumerable <int> GetIterator() { Console.WriteLine( "Iterator returned 1"); yield return 1; Console.WriteLine( "Iterator returned 2"); yield break; Console.WriteLine( "Iterator returned 3 "); 利回りリターン3; }
(4)注意事項
<1> foreachループを実行するときにスレッドの安全性を考慮する
foreach中にトラバースされたコレクションの操作を削除および追加しようとしないでください。
スレッドセーフとしてマークされているコレクションであっても、foreachの際にアイテムを追加および削除すると例外が発生します。
<2> IEnumerableインターフェイスは、LINQ機能のコアインターフェイスです。
IEnumerableインターフェイスを実装するコレクションのみ
select、whereなどの関連するLINQ操作を実行するには
LINQの特定の操作については、次のセクションが継承します。
2.8ラムダ式
ラムダ式は、単純な方法で匿名メソッドを記述するだけで、.NETデリゲート型の使用を完全に簡素化します。
ラムダ式はC#で「arg-list => expr-body」として記述され、「=>」記号の左側は式のパラメーターリスト、右側は式の本体(本体)です。パラメーターリストには、0個以上のパラメーターをコンマで区切って含めることができます。
上記の匿名メソッドの例から、次の2つのコードが同等であることがわかります。
//匿名メソッド Func <int、int、string> func2 = delegate(int a、int b) { return a + "+" + b + "is equal to?" + Environment.NewLine +(a + b).ToString(); }; //ラムダ式 Func <int、int、string> func3 = (a、b)=> {return a + "+" + b + "equal to what?" + Environment.NewLine +(a + b) ToString();};
ラムダ式は数学のラムダ(ギリシャの11番目の文字)計算に基づいて名前が付けられ、「ラムダ式」は匿名メソッドを簡単に書くことを指します。
3.重要なポイント:
A. LINQ、Language Integrated Query(Language Integrated Query)は、データベースのクエリのようにメモリデータ(コレクションなど)を操作できるようにする言語拡張です。
B.匿名型: newを使用して匿名型を宣言する場合、型を指定する必要はありません。.NET3.0以降では、型の割り当てと属性名の割り当てを自動的に完了することができます。
C.自動属性: .net 3.0以降のバージョンでは、属性を定義し、get; set;と書くだけで済みます。.Netは、コンパイルフェーズ中に書き込みを完了するのに役立ち、パフォーマンスの問題は発生しません。
D.イニシャライザ: 3.0以降のバージョンでは、オブジェクトの初期化、特にジェネリックコレクションの割り当てを簡単に記述できます。これは非常に簡潔で明確です。
E.匿名メソッド:メソッドを委任する場合、メソッド名を指定する必要はありません。匿名メソッドを使用すると、コンテキスト内の変数にアクセスできます。メソッドコードが少ない場合は、軽量で委任を実装するのが非常に実用的です。
F.拡張メソッド:継承を使用せずに型に動作を追加できます
G.イテレーター:巨大なコレクションをトラバースする場合、条件が満たされている限り、すべてをメモリーにロードする必要はありません。
H.ラムダ式:ラムダ式は、数学のλ(ギリシャの11番目の文字)計算に基づいて命名され、「ラムダ式」(ラムダ式)は、匿名メソッドを簡単に書くことを指します。
備考:この記事はブロガーの記事を参照していますが、多数あります。
LINQの使用については、次のセクションで詳しく説明します。