2013-01-19T22:42:35の更新内容

programming/netfx/enumeration/index.wiki.txt

current previous
3,9 3,7
 
${smdncms:keywords,IEnumerable,IEnumerator,foreach,for,列挙子,反復子,イテレータ}
${smdncms:keywords,IEnumerable,IEnumerator,foreach,for,列挙子,反復子,イテレータ}
 
${smdncms:document_versions,codelang=cs,codelang=vb}
${smdncms:document_versions,codelang=cs,codelang=vb}
 

        

        
~
C#やVB.NETでは、コレクションの各要素に対する繰り返しを行う構文として、foreach文/For Eachステートメントが用意されています。 また、.NET FrameworkにはIEnumerableとIEnumeratorという列挙処理をサポートするためのインターフェイスが用意されています。
C#やVB.NETでは、コレクションの各要素に対する繰り返しを行う構文として、foreach文/For Eachステートメントが用意されています。 また、.NET FrameworkにはIEnumerableとIEnumeratorという列挙処理をサポートするためのインターフェイスが用意されています。 ここでは、列挙操作と列挙子のインターフェイスについて解説します。
+

          
+
IEnumerableとはオブジェクトが列挙(foreach)可能であることを表すインターフェイス、IEnumeratorはオブジェクト内の要素を列挙(foreach)する機能を提供するインターフェイスです。 ここでは、列挙の構文とインターフェイスとの関わりやその動作、また各インターフェイスの実装方法などについて解説します。
 

        

        
 
-関連するページ
-関連するページ
 
--[[programming/netfx/arrays]]
--[[programming/netfx/arrays]]
265,9 263,9
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
~
このコードはfor文での列挙は問題なく出来ますが、コメントにあるエラーメッセージの通りforeach文での列挙はコンパイルエラーとなります。
コメントでも書いている通り、このコードはfor文での列挙は問題なく出来ますが、foreach文での列挙はコンパイルエラーとなります。
 

        

        
~
ここまでの例を見て分かる通り、foreach文で列挙できるかどうかは、配列やコレクションのようにインデクサをサポートしているかどうかとは別の理由によるものであるということが分かると思います。 結論から言うと、foreach文で列挙できるかどうかは、''列挙しようとするオブジェクトがIEnumerableインターフェイスを実装しているかどうか''で決まります。
ここまでの例を見て分かる通り、foreach文で列挙できるかどうかは、配列やコレクションのようにインデクサをサポートしているかどうかとは別の理由によるものであるということが分かると思います。
 

        

        
 
**foreach文とIEnumerable, IEnumeratorの関係
**foreach文とIEnumerable, IEnumeratorの関係
 
foreach文/For Eachステートメントでの列挙操作を出来るようにするためには、列挙される型が&msdn(netfx,type,System.Collections.IEnumerable){IEnumerableインターフェイス};を実装していなければなりません。 IEnumerableインターフェイスは、型が''列挙可能''(enumerable)であることを表すためのインターフェイスです。 型がこのインターフェイスを実装している場合、foreach文での列挙が出来るようになります。 配列やコレクションクラスがforeach文で列挙できるのは、配列の実体であるArrayクラスや個々のコレクションクラスがIEnumerableインターフェイスを実装しているためです。
foreach文/For Eachステートメントでの列挙操作を出来るようにするためには、列挙される型が&msdn(netfx,type,System.Collections.IEnumerable){IEnumerableインターフェイス};を実装していなければなりません。 IEnumerableインターフェイスは、型が''列挙可能''(enumerable)であることを表すためのインターフェイスです。 型がこのインターフェイスを実装している場合、foreach文での列挙が出来るようになります。 配列やコレクションクラスがforeach文で列挙できるのは、配列の実体であるArrayクラスや個々のコレクションクラスがIEnumerableインターフェイスを実装しているためです。
1142,7 1140,7
 
   場所 Sample.Main()
   場所 Sample.Main()
 
}}
}}
 

        

        
~
これを回避するには、foreachによる列挙中はコレクションを変更しないようにするしかありません。 逆に言えば、''foreachでの列挙中''に''列挙中のコレクションを変更''しなければよいため、次のような代替手段を使うことができます。
これを回避するには、foreachによる列挙中はコレクションを変更しないようにするしかありません。 そこで、いくつかの代替手段が挙げられます。
 

        

        
 
**for文を使う
**for文を使う
 
一つの代替方法に、for文などを使いインデックスを指定してコレクションを列挙・変更する方法があります。 この方法では、コレクションを変更することにより列挙中の要素のインデックスが変わる場合がある点に注意が必要です。 先の例を、for文/Do Whileステートメントを使って書き換えると次のようになります。
一つの代替方法に、for文などを使いインデックスを指定してコレクションを列挙・変更する方法があります。 この方法では、コレクションを変更することにより列挙中の要素のインデックスが変わる場合がある点に注意が必要です。 先の例を、for文/Do Whileステートメントを使って書き換えると次のようになります。

programming/netfx/locale/0_abstract/index.wiki.txt

current previous
146,69 146,6
 

        

        
 
}}
}}
 

        

        
+
.NET Frameworkが3.5以前のバージョンでThread.CurrentThread.CurrentCultureプロパティを設定する場合、書式プロバイダとして使用できない[[ニュートラルカルチャ(後述)>#neutral_culture]]を設定しようとすると次の例のようにNotSupportedExceptionがスローされます。 Thread.CurrentThread.CurrentCultureプロパティを設定する場合は、国・地域に固有な(ニュートラルでない)カルチャを設定する必要があります。
+

          
+
.NET Framework 4.0以降ではThread.CurrentThread.CurrentCultureプロパティにニュートラルカルチャを設定することができ、この場合例外はスローされません。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Globalization;
+
using System.Threading;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // 現在のスレッドのカルチャをen-US(英語/アメリカ合衆国)に変更
+
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+

          
+
    Console.WriteLine("CultureInfo.CurrentCulture: {0}", CultureInfo.CurrentCulture);
+

          
+
    // 現在のスレッドのカルチャをニュートラルカルチャ"en"に変更しようとする
+
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
+

          
+
    Console.WriteLine("CultureInfo.CurrentCulture: {0}", CultureInfo.CurrentCulture);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Globalization
+
Imports System.Threading
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 現在のスレッドのカルチャをen-US(英語/アメリカ合衆国)に変更
+
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
+

          
+
    Console.WriteLine("CultureInfo.CurrentCulture: {0}", CultureInfo.CurrentCulture)
+

          
+
    ' 現在のスレッドのカルチャをニュートラルカルチャ"en"に変更しようとする
+
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en")
+

          
+
    Console.WriteLine("CultureInfo.CurrentCulture: {0}", CultureInfo.CurrentCulture)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(.NET Framework 3.5以前での実行結果){{
+
CultureInfo.CurrentCulture: en-US
+

          
+
ハンドルされていない例外: System.NotSupportedException: カルチャ 'en' はニュートラル カルチャです。フォーマットや解析に使用できません、スレッドの現在のカルチャとして設定することもできません。
+
   場所 System.Globalization.CultureInfo.CheckNeutral(CultureInfo culture)
+
   場所 System.Threading.Thread.set_CurrentCulture(CultureInfo value)
+
   場所 Sample.Main()
+
}}
+

          
+
#prompt(.NET Framework 4以降での実行結果){{
+
CultureInfo.CurrentCulture: en-US
+
CultureInfo.CurrentCulture: en
+
}}
+

          
+

          
 
**カルチャと書式・テキスト処理
**カルチャと書式・テキスト処理
 
いくつかのクラスやメソッドでは、カルチャよって異なる結果を返すものがあります。 一つの例として、&msdn(netfx,member,System.DateTime.ToString){DateTime.ToStringメソッド};は、書式を指定しなかった場合は現在のカルチャに設定されている書式に従って文字列化します。
いくつかのクラスやメソッドでは、カルチャよって異なる結果を返すものがあります。 一つの例として、&msdn(netfx,member,System.DateTime.ToString){DateTime.ToStringメソッド};は、書式を指定しなかった場合は現在のカルチャに設定されている書式に従って文字列化します。
 

        

        
485,16 422,6
 

        

        
 
なお、CultureInfo.InvariantCultureを使用しなくても、文字列関連のクラスではStringComparison.InvariantCultureやString.ToLowerInvariant、String.CompareInvariantなどを使うことでインバリアントカルチャの規則を使って処理を行うことができるようになっています。
なお、CultureInfo.InvariantCultureを使用しなくても、文字列関連のクラスではStringComparison.InvariantCultureやString.ToLowerInvariant、String.CompareInvariantなどを使うことでインバリアントカルチャの規則を使って処理を行うことができるようになっています。
 

        

        
+
**ニュートラルカルチャ [#neutral_culture]
+
ニュートラルカルチャとは、国や地域に依存せず、言語のみに依存するカルチャです。 例えば、"en-US"(英語-米国)や"en-GB"(英語-英国)のカルチャは言語と地域を表しますが、対してニュートラルカルチャ"en"(英語)は言語のみを表します。
+

          
+
.NET Framework 3.5以前では、ニュートラルカルチャから''言語に対応する情報''を取得することはできますが、''国や地域に対応する情報''を取得することはできません。 従って、ニュートラルカルチャの場合は、DateTimeFormatやNumberFormatなどの書式を取得したり、書式プロバイダ(詳細:[[programming/netfx/locale/1_infoes]])として使用することは出来ません。 また、既に解説したとおり、Thread.''CurrentUICulture''にはニュートラルカルチャを指定することが出来ますが、書式情報を取得することが出来ないニュートラルカルチャをThread.''CurrentCulture''に指定することは出来ません。 このような操作を行おうとした場合、NotSupportedExceptionがスローされます。
+

          
+
.NET Framework 4以降では、ニュートラルカルチャに特定のカルチャが関連付けられるようになったためこのような制限は無くなり、書式を取得したり書式プロバイダとして使用することや、Thread.CurrentCultureにニュートラルカルチャを設定することが出来るようになっています。
+

          
+
なお、ニュートラルカルチャを取得するには"ja"や"en"などの言語コードのみを指定します。 CultureInfoがニュートラルカルチャかどうか調べるには、&msdn(netfx,member,System.Globalization.CultureInfo.IsNeutralCulture){IsNeutralCultureプロパティ};を参照します。
+

          
+

          
 
*カルチャ情報の取得 (CultureInfo)
*カルチャ情報の取得 (CultureInfo)
 
**カルチャに固有な情報の取得
**カルチャに固有な情報の取得
 
CultureInfoクラスのプロパティを参照することで、カルチャに固有な情報を取得することが出来ます。 ロケールの固有なIDである&msdn(netfx,member,System.Globalization.CultureInfo.LCID){LCID};を始め、ISO 639-2形式の言語コードISOを取得する&msdn(netfx,member,System.Globalization.CultureInfo.TwoLetterISOLanguageName){TwoLetterISOLanguageName};、&msdn(netfx,member,System.Globalization.CultureInfo.ThreeLetterISOLanguageName){ThreeLetterISOLanguageName};などのプロパティがあります。
CultureInfoクラスのプロパティを参照することで、カルチャに固有な情報を取得することが出来ます。 ロケールの固有なIDである&msdn(netfx,member,System.Globalization.CultureInfo.LCID){LCID};を始め、ISO 639-2形式の言語コードISOを取得する&msdn(netfx,member,System.Globalization.CultureInfo.TwoLetterISOLanguageName){TwoLetterISOLanguageName};、&msdn(netfx,member,System.Globalization.CultureInfo.ThreeLetterISOLanguageName){ThreeLetterISOLanguageName};などのプロパティがあります。
612,6 539,8
 

        

        
 
一方、&msdn(netfx,member,System.Globalization.CultureInfo.GetCultureInfo){GetCultureInfoメソッド};も同様に名前やIDを使ってCultureInfoを取得することが出来ますが、このメソッドは読み取り専用のインスタンスを返すため、変更する事は出来ません。 また、キャッシュされた情報を元に作成するため、コンストラクタを使う場合よりもパフォーマンスに優れています。
一方、&msdn(netfx,member,System.Globalization.CultureInfo.GetCultureInfo){GetCultureInfoメソッド};も同様に名前やIDを使ってCultureInfoを取得することが出来ますが、このメソッドは読み取り専用のインスタンスを返すため、変更する事は出来ません。 また、キャッシュされた情報を元に作成するため、コンストラクタを使う場合よりもパフォーマンスに優れています。
 

        

        
-
また、国や地域に依存せず、言語のみに依存するカルチャ(''ニュートラルカルチャ'')を取得するには"ja"や"en"などの言語コードのみを指定します。 ニュートラルカルチャの場合は、DateTimeFormatやNumberFormatを取得したり、書式プロバイダとして使用することは出来ません。 ニュートラルカルチャかどうか調べるには、&msdn(netfx,member,System.Globalization.CultureInfo.IsNeutralCulture){IsNeutralCultureプロパティ};を参照します。 なお、Thread.CurrentUICultureにはニュートラルカルチャを指定することが出来ますがThread.CurrentCultureには指定することは出来ません。
-

          
 
以下の例では、いくつかのカルチャとニュートラルカルチャを取得し、プロパティの内容を表示しています。 また、ニュートラルカルチャでない場合は、カルチャ固有の書式を使ってDateTimeとDecimalの値を書式化しています。
以下の例では、いくつかのカルチャとニュートラルカルチャを取得し、プロパティの内容を表示しています。 また、ニュートラルカルチャでない場合は、カルチャ固有の書式を使ってDateTimeとDecimalの値を書式化しています。
 

        

        
 
#tabpage(C#)
#tabpage(C#)

programming/netfx/arrays/2_operations/index.wiki.txt

current previous
1409,8 1409,6
 
**要素の位置の検索 (IndexOf, LastIndexOf, BinarySearch) [#Array.IndexOf]
**要素の位置の検索 (IndexOf, LastIndexOf, BinarySearch) [#Array.IndexOf]
 
&msdn(netfx,member,System.Array.IndexOf){Array.IndexOfメソッド};を使うことで配列内における指定した値を持つ要素の位置を検索して取得することが出来ます。 このメソッドは配列の前方から検索を行うため、配列内に同一の値を持つ要素がある場合は、そのうちより小さい(最初に見つかった)インデックスを返します。 逆に、&msdn(netfx,member,System.Array.LastIndexOf){Array.LastIndexOfメソッド};は配列の後方から検索を行うため、より大きい(前方から見て最後に見つかった)インデックスを返します。 どちらのメソッドも、配列内に該当する要素が無い場合は-1が返されます。
&msdn(netfx,member,System.Array.IndexOf){Array.IndexOfメソッド};を使うことで配列内における指定した値を持つ要素の位置を検索して取得することが出来ます。 このメソッドは配列の前方から検索を行うため、配列内に同一の値を持つ要素がある場合は、そのうちより小さい(最初に見つかった)インデックスを返します。 逆に、&msdn(netfx,member,System.Array.LastIndexOf){Array.LastIndexOfメソッド};は配列の後方から検索を行うため、より大きい(前方から見て最後に見つかった)インデックスを返します。 どちらのメソッドも、配列内に該当する要素が無い場合は-1が返されます。
 

        

        
+
なお、Array.IndexOf, Array.LastIndexOfメソッドでは多次元配列内の要素の位置を検索することは出来ません。 メソッドに多次元配列を指定すると、&msdn(netfx,type,System.RankException){RankException};がスローされます。
+

          
 
#tabpage(C#)
#tabpage(C#)
 
#code(cs,要素の位置の検索){{
#code(cs,要素の位置の検索){{
 
using System;
using System;
1516,8 1514,6
 
BinarySearch(7) = -13
BinarySearch(7) = -13
 
}}
}}
 

        

        
+
なお、Array.BinarySearchメソッドもArray.IndexOfメソッドと同様、多次元配列内の要素の位置を検索することは出来ません。 メソッドに多次元配列を指定すると、&msdn(netfx,type,System.RankException){RankException};がスローされます。
+

          
 
***IndexOfとBinarySearchの速度比較
***IndexOfとBinarySearchの速度比較
 
参考までに、Array.IndexOfメソッドとArray.BinarySearchメソッドを使った場合の速度の違いを比較した結果を紹介します。 次のように、IndexOfメソッドを使った検索では配列の要素数が増えるにつれ多大な時間がかかるようになっていますが、BinarySearchメソッドを使った検索では配列の要素数が増えても比較的短い時間で結果が得られています。
参考までに、Array.IndexOfメソッドとArray.BinarySearchメソッドを使った場合の速度の違いを比較した結果を紹介します。 次のように、IndexOfメソッドを使った検索では配列の要素数が増えるにつれ多大な時間がかかるようになっていますが、BinarySearchメソッドを使った検索では配列の要素数が増えても比較的短い時間で結果が得られています。