この記事では、この API のリファレンス ドキュメントに補足的な解説を提供します。
NotSupportedException は、呼び出されたメソッドまたはプロパティの実装が存在しないことを示します。
NotSupportedException は、値が0x80131515を持つ HRESULT COR_E_NOTSUPPORTED
を使用します。
NotSupportedExceptionのインスタンスの初期プロパティ値の一覧については、NotSupportedExceptionコンストラクターを参照してください。
NotSupportedException 例外をスローする
次の場合は、 NotSupportedException 例外をスローすることを検討してください。
汎用インターフェイスを実装しており、メソッドの数には意味のある実装がありません。 たとえば、 IConvertible インターフェイスを実装する日時型を作成する場合、ほとんどの変換で NotSupportedException 例外がスローされます。
多くのメソッドをオーバーライドする必要がある抽象クラスから継承しました。 ただし、これらのサブセットの実装を提供する準備は整っているだけです。 実装しないことを決定したメソッドでは、 NotSupportedExceptionをスローすることを選択できます。
条件付きで操作を有効にする状態で汎用型を定義しています。 たとえば、型は読み取り専用または読み取り/書き込みのいずれかになります。 その場合:
オブジェクトが読み取り専用の場合、インスタンスの状態を変更するインスタンスまたは呼び出しメソッドのプロパティに値を割り当てようとすると、 NotSupportedException 例外がスローされます。
特定の機能が使用可能かどうかを示す Boolean 値を返すプロパティを実装する必要があります。 たとえば、読み取り専用または読み取り/書き込みのいずれかの型の場合は、一連の読み取り/書き込みメソッドを使用できるかどうかを示す
IsReadOnly
プロパティを実装できます。
NotSupportedException 例外を処理する
NotSupportedException例外は、メソッドに実装がなく、呼び出してはならないことを示します。 例外を処理しないでください。 代わりに、例外の原因によって異なります。実装が完全に存在しないか、メンバーの呼び出しがオブジェクトの目的と矛盾しているか (読み取り専用のFileStream オブジェクトに対するFileStream.Write メソッドの呼び出しなど)。
操作を意味のある方法で実行できないため、実装が提供されていません。 これは、抽象基底クラスのメソッドの実装を提供するオブジェクト、または汎用インターフェイスを実装するオブジェクトでメソッドを呼び出す場合に一般的な例外であり、メソッドに意味のある実装がない場合です。
たとえば、 Convert クラスは IConvertible インターフェイスを実装します。つまり、すべてのプリミティブ型を他のすべてのプリミティブ型に変換するメソッドを含める必要があります。 ただし、これらの変換の多くは不可能です。 その結果、たとえば、Convert.ToBoolean(DateTime) メソッドの呼び出しは、DateTimeとBoolean値の間で変換できないため、NotSupportedException例外をスローします。
例外を排除するには、メソッド呼び出しを排除する必要があります。
オブジェクトの状態を指定すると、メソッド呼び出しはサポートされません。 オブジェクトの状態のために機能が使用できないメンバーを呼び出そうとしています。 例外は、次の 3 つの方法のいずれかで排除できます。
オブジェクトの状態は事前にわかっていますが、サポートされていないメソッドまたはプロパティを呼び出しました。 この場合、メンバーの呼び出しはエラーであり、削除できます。
オブジェクトの状態は事前にわかっていますが (通常、コードでインスタンス化されているため)、オブジェクトが正しく構成されていません。 次の例は、この問題を示しています。 読み取り専用の FileStream オブジェクトを作成し、それに書き込もうとします。
using System; using System.IO; using System.Text; using System.Threading.Tasks; public class Example { public static async Task Main() { Encoding enc = Encoding.Unicode; String value = "This is a string to persist."; Byte[] bytes = enc.GetBytes(value); FileStream fs = new FileStream(@".\TestFile.dat", FileMode.Open, FileAccess.Read); Task t = fs.WriteAsync(enc.GetPreamble(), 0, enc.GetPreamble().Length); Task t2 = t.ContinueWith((a) => fs.WriteAsync(bytes, 0, bytes.Length)); await t2; fs.Close(); } } // The example displays the following output: // Unhandled Exception: System.NotSupportedException: Stream does not support writing. // at System.IO.Stream.BeginWriteInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state // , Boolean serializeAsynchronously) // at System.IO.FileStream.BeginWrite(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object sta // teObject) // at System.IO.Stream.<>c.<BeginEndWriteAsync>b__53_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, // Object state) // at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet // hod, Func`3 endMethod) // at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count) // at System.IO.FileStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) // at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count) // at Example.Main()
open System.IO open System.Text let main = task { let enc = Encoding.Unicode let value = "This is a string to persist." let bytes = enc.GetBytes value let fs = new FileStream(@".\TestFile.dat", FileMode.Open, FileAccess.Read) let t = fs.WriteAsync(enc.GetPreamble(), 0, enc.GetPreamble().Length) let t2 = t.ContinueWith(fun a -> fs.WriteAsync(bytes, 0, bytes.Length)) let! _ = t2 fs.Close() } main.Wait() // The example displays the following output: // Unhandled Exception: System.NotSupportedException: Stream does not support writing. // at System.IO.Stream.BeginWriteInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state // , Boolean serializeAsynchronously) // at System.IO.FileStream.BeginWrite(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object sta // teObject) // at System.IO.Stream.<>c.<BeginEndWriteAsync>b__53_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, // Object state) // at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet // hod, Func`3 endMethod) // at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count) // at System.IO.FileStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) // at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count) // at <StartupCode:fs>.main()
Imports System.IO Imports System.Text Imports System.Threading.Tasks Module Example Public Sub Main() Dim enc As Encoding = Encoding.Unicode Dim value As String = "This is a string to persist." Dim bytes() As Byte = enc.GetBytes(value) Dim fs As New FileStream(".\TestFile.dat", FileMode.Open, FileAccess.Read) Dim t As Task = fs.WriteAsync(enc.GetPreamble(), 0, enc.GetPreamble().Length) Dim t2 As Task = t.ContinueWith(Sub(a) fs.WriteAsync(bytes, 0, bytes.Length)) t2.Wait() fs.Close() End Sub End Module ' The example displays the following output: ' Unhandled Exception: System.NotSupportedException: Stream does not support writing. ' at System.IO.Stream.BeginWriteInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state ' , Boolean serializeAsynchronously) ' at System.IO.FileStream.BeginWrite(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object sta ' teObject) ' at System.IO.Stream.<>c.<BeginEndWriteAsync>b__53_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, ' Object state) ' at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet ' hod, Func`3 endMethod) ' at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count) ' at System.IO.FileStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) ' at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count) ' at Example.Main()
インスタンス化されたオブジェクトが目的の機能をサポートしていることを確認することで、Ycan は例外を排除します。 次の例では、FileStream.FileStream(String, FileMode, FileAccess) コンストラクターに正しい引数を指定することで、読み取り専用のFileStream オブジェクトの問題に対処します。
オブジェクトの状態は事前に把握されておらず、オブジェクトは特定の操作をサポートしていません。 ほとんどの場合、オブジェクトには、特定の操作セットをサポートするかどうかを示すプロパティまたはメソッドを含める必要があります。 オブジェクトの値を確認し、必要に応じてメンバーを呼び出すことで、例外を排除できます。
次の例では、読み取りアクセスをサポートしていないストリームの先頭から読み取ろうとしたときにNotSupportedException例外をスローする
DetectEncoding
メソッドを定義します。using System; using System.IO; using System.Threading.Tasks; public class TestPropEx1 { public static async Task Main() { String name = @".\TestFile.dat"; var fs = new FileStream(name, FileMode.Create, FileAccess.Write); Console.WriteLine("Filename: {0}, Encoding: {1}", name, await FileUtilities1.GetEncodingType(fs)); } } public class FileUtilities1 { public enum EncodingType { None = 0, Unknown = -1, Utf8 = 1, Utf16 = 2, Utf32 = 3 } public async static Task<EncodingType> GetEncodingType(FileStream fs) { Byte[] bytes = new Byte[4]; int bytesRead = await fs.ReadAsync(bytes, 0, 4); if (bytesRead < 2) return EncodingType.None; if (bytesRead >= 3 & (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)) return EncodingType.Utf8; if (bytesRead == 4) { var value = BitConverter.ToUInt32(bytes, 0); if (value == 0x0000FEFF | value == 0xFEFF0000) return EncodingType.Utf32; } var value16 = BitConverter.ToUInt16(bytes, 0); if (value16 == (ushort)0xFEFF | value16 == (ushort)0xFFFE) return EncodingType.Utf16; return EncodingType.Unknown; } } // The example displays the following output: // Unhandled Exception: System.NotSupportedException: Stream does not support reading. // at System.IO.FileStream.BeginRead(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback callback, Object state) // at System.IO.Stream.<>c.<BeginEndReadAsync>b__46_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state) // at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance, TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod) // at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count) // at System.IO.FileStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) // at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count) // at FileUtilities.GetEncodingType(FileStream fs) in C:\Work\docs\program.cs:line 26 // at Example.Main() in C:\Work\docs\program.cs:line 13 // at Example.<Main>()
open System open System.IO module FileUtilities = type EncodingType = | None = 0 | Unknown = -1 | Utf8 = 1 | Utf16 = 2 | Utf32 = 3 let getEncodingType (fs: FileStream) = task { let bytes = Array.zeroCreate<byte> 4 let! bytesRead = fs.ReadAsync(bytes, 0, 4) if bytesRead < 2 then return EncodingType.None elif bytesRead >= 3 && bytes[0] = 0xEFuy && bytes[1] = 0xBBuy && bytes[2] = 0xBFuy then return EncodingType.Utf8 else let value = BitConverter.ToUInt32(bytes, 0) if bytesRead = 4 && (value = 0x0000FEFFu || value = 0xFEFF0000u) then return EncodingType.Utf32 else let value16 = BitConverter.ToUInt16(bytes, 0) if value16 = 0xFEFFus || value16 = 0xFFFEus then return EncodingType.Utf16 else return EncodingType.Unknown } let main _ = task { let name = @".\TestFile.dat" let fs = new FileStream(name, FileMode.Create, FileAccess.Write) let! et = FileUtilities.getEncodingType fs printfn $"Filename: {name}, Encoding: {et}" } // The example displays the following output: // Unhandled Exception: System.NotSupportedException: Stream does not support reading. // at System.IO.FileStream.BeginRead(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback callback, Object state) // at System.IO.Stream.<>c.<BeginEndReadAsync>b__46_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state) // at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance, TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod) // at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count) // at System.IO.FileStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) // at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count) // at FileUtilities.GetEncodingType(FileStream fs) // at Example.Main() // at Example.<Main>()
Imports System.IO Imports System.Threading.Tasks Module Example2 Public Sub Main() Dim name As String = ".\TestFile.dat" Dim fs As New FileStream(name, FileMode.Create, FileAccess.Write) Console.WriteLine("Filename: {0}, Encoding: {1}", name, FileUtilities2.GetEncodingType(fs)) End Sub End Module Public Class FileUtilities2 Public Enum EncodingType As Integer None = 0 Unknown = -1 Utf8 = 1 Utf16 = 2 Utf32 = 3 End Enum Public Shared Function GetEncodingType(fs As FileStream) As EncodingType Dim bytes(3) As Byte Dim t As Task(Of Integer) = fs.ReadAsync(bytes, 0, 4) t.Wait() Dim bytesRead As Integer = t.Result If bytesRead < 2 Then Return EncodingType.None If bytesRead >= 3 And (bytes(0) = &HEF AndAlso bytes(1) = &HBB AndAlso bytes(2) = &HBF) Then Return EncodingType.Utf8 End If If bytesRead = 4 Then Dim value As UInteger = BitConverter.ToUInt32(bytes, 0) If value = &HFEFF Or value = &HFEFF0000 Then Return EncodingType.Utf32 End If End If Dim value16 As UInt16 = BitConverter.ToUInt16(bytes, 0) If value16 = &HFEFF Or value16 = &HFFFE Then Return EncodingType.Utf16 End If Return EncodingType.Unknown End Function End Class ' The example displays the following output: ' Unhandled Exception: System.NotSupportedException: Stream does not support reading. ' at System.IO.Stream.BeginReadInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state, ' Boolean serializeAsynchronously) ' at System.IO.FileStream.BeginRead(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object stat ' eObject) ' at System.IO.Stream.<>c.<BeginEndReadAsync>b__43_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, O ' bject state) ' at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMet ' hod, Func`3 endMethod) ' at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count) ' at System.IO.FileStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) ' at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count) ' at FileUtilities2.GetEncodingType(FileStream fs) ' at Example.Main()
FileStream.CanRead プロパティの値を調べ、ストリームが読み取り専用の場合はメソッドを終了することで、例外を排除できます。
public static async Task<EncodingType> GetEncodingType(FileStream fs) { if (!fs.CanRead) return EncodingType.Unknown; Byte[] bytes = new Byte[4]; int bytesRead = await fs.ReadAsync(bytes, 0, 4); if (bytesRead < 2) return EncodingType.None; if (bytesRead >= 3 & (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)) return EncodingType.Utf8; if (bytesRead == 4) { var value = BitConverter.ToUInt32(bytes, 0); if (value == 0x0000FEFF | value == 0xFEFF0000) return EncodingType.Utf32; } var value16 = BitConverter.ToUInt16(bytes, 0); if (value16 == (ushort)0xFEFF | value16 == (ushort)0xFFFE) return EncodingType.Utf16; return EncodingType.Unknown; } } // The example displays the following output: // Filename: .\TestFile.dat, Encoding: Unknown
let getEncodingType (fs: FileStream) = task { if not fs.CanRead then return EncodingType.Unknown else let bytes = Array.zeroCreate<byte> 4 let! bytesRead = fs.ReadAsync(bytes, 0, 4) if bytesRead < 2 then return EncodingType.None elif bytesRead >= 3 && bytes[0] = 0xEFuy && bytes[1] = 0xBBuy && bytes[2] = 0xBFuy then return EncodingType.Utf8 else let value = BitConverter.ToUInt32(bytes, 0) if bytesRead = 4 && (value = 0x0000FEFFu || value = 0xFEFF0000u) then return EncodingType.Utf32 else let value16 = BitConverter.ToUInt16(bytes, 0) if value16 = 0xFEFFus || value16 = 0xFFFEus then return EncodingType.Utf16 else return EncodingType.Unknown } // The example displays the following output: // Filename: .\TestFile.dat, Encoding: Unknown
Public Class FileUtilities3 Public Enum EncodingType As Integer None = 0 Unknown = -1 Utf8 = 1 Utf16 = 2 Utf32 = 3 End Enum Public Shared Function GetEncodingType(fs As FileStream) As EncodingType If Not fs.CanRead Then Return EncodingType.Unknown End If Dim bytes(3) As Byte Dim t As Task(Of Integer) = fs.ReadAsync(bytes, 0, 4) t.Wait() Dim bytesRead As Integer = t.Result If bytesRead < 2 Then Return EncodingType.None If bytesRead >= 3 And (bytes(0) = &HEF AndAlso bytes(1) = &HBB AndAlso bytes(2) = &HBF) Then Return EncodingType.Utf8 End If If bytesRead = 4 Then Dim value As UInteger = BitConverter.ToUInt32(bytes, 0) If value = &HFEFF Or value = &HFEFF0000 Then Return EncodingType.Utf32 End If End If Dim value16 As UInt16 = BitConverter.ToUInt16(bytes, 0) If value16 = &HFEFF Or value16 = &HFFFE Then Return EncodingType.Utf16 End If Return EncodingType.Unknown End Function End Class ' The example displays the following output: ' Filename: .\TestFile.dat, Encoding: Unknown
関連する例外の種類
NotSupportedException例外は、他の 2 つの例外の種類と密接に関連しています。
-
この例外は、メソッドを実装できるが、新しいバージョンでメンバーが実装される、メンバーが特定のプラットフォームで使用できない、またはメンバーが抽象クラスに属していて、派生クラスが実装を提供する必要があるため、メソッドを実装できない場合にスローされます。
-
この例外は、通常、オブジェクトが要求された操作を実行できる場合があり、オブジェクトの状態によって操作を実行できるかどうかを決定するシナリオでスローされます。
.NET Compact Framework の注意事項
.NET Compact Framework を使用し、ネイティブ関数で P/Invoke を使用する場合、次の場合にこの例外がスローされることがあります。
- マネージド コードでの宣言が正しくありません。
- .NET Compact Framework では、実行しようとしている操作はサポートされていません。
- DLL 名はエクスポート時にマングルされます。
NotSupportedException例外がスローされた場合は、次の項目を確認します。
- .NET Compact Framework P/Invoke の制限に違反した場合。
- 事前に割り当てられたメモリを必要とする引数の場合。 これらが存在する場合は、既存の変数への参照を渡す必要があります。
- エクスポートされた関数の名前が正しいこと。 これは、 DumpBin.exeで確認できます。
- 引数を渡そうとしていない。
.NET