System.NotSupportedException, klasa
Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.
NotSupportedException wskazuje, że żadna implementacja nie istnieje dla wywoływanej metody lub właściwości.
NotSupportedException używa hrESULT COR_E_NOTSUPPORTED
, który ma wartość 0x80131515.
Aby uzyskać listę początkowych wartości właściwości dla wystąpienia NotSupportedExceptionprogramu , zobacz NotSupportedException konstruktory.
Zgłaszanie wyjątku NotSupportedException
Możesz rozważyć zgłoszenie wyjątku NotSupportedException w następujących przypadkach:
Implementujesz interfejs ogólnego przeznaczenia, a liczba metod nie ma znaczącej implementacji. Jeśli na przykład tworzysz typ daty i godziny implementujący IConvertible interfejs, zgłosisz NotSupportedException wyjątek dla większości konwersji.
Odziedziczono po klasie abstrakcyjnej, która wymaga zastąpienia wielu metod. Jednak możesz przygotować się tylko do udostępnienia implementacji dla podzbioru tych elementów. W przypadku metod, których nie chcesz implementować, możesz zgłosić wartość NotSupportedException.
Definiujesz typ ogólnego przeznaczenia ze stanem, który umożliwia warunkowe wykonywanie operacji. Na przykład typ może być tylko do odczytu lub do odczytu i zapisu. W takim przypadku:
Jeśli obiekt jest tylko do odczytu, próba przypisania wartości do właściwości wystąpienia lub metod wywołania, które modyfikują NotSupportedException stan wystąpienia, powinny zgłosić wyjątek.
Należy zaimplementować właściwość zwracającą wartość wskazującą Boolean , czy dana funkcja jest dostępna. Na przykład w przypadku typu, który może być tylko do odczytu lub do odczytu i zapisu, można zaimplementować właściwość wskazującą
IsReadOnly
, czy zestaw metod odczytu i zapisu jest dostępny, czy niedostępny.
Obsługa wyjątku NotSupportedException
Wyjątek NotSupportedException wskazuje, że metoda nie ma implementacji i że nie należy jej wywoływać. Nie należy obsługiwać wyjątku. Zamiast tego, co należy zrobić, zależy od przyczyny wyjątku: czy implementacja jest całkowicie nieobecna, czy wywołanie elementu członkowskiego jest niespójne z celem obiektu (na przykład wywołanie metody w obiekcie tylko FileStream do FileStream.Write odczytu).
Nie podano implementacji, ponieważ nie można wykonać operacji w zrozumiały sposób. Jest to typowy wyjątek podczas wywoływania metod na obiekcie, który zapewnia implementacje metod abstrakcyjnej klasy bazowej lub implementuje interfejs ogólnego przeznaczenia, a metoda nie ma znaczącej implementacji.
Na przykład Convert klasa implementuje IConvertible interfejs, co oznacza, że musi zawierać metodę, aby przekonwertować każdy typ pierwotny na każdy inny typ pierwotny. Wiele z tych konwersji nie jest jednak możliwe. W związku z tym wywołanie Convert.ToBoolean(DateTime) metody, na przykład, zgłasza NotSupportedException wyjątek, ponieważ nie ma możliwej konwersji między wartością Boolean a DateTime a
Aby wyeliminować wyjątek, należy wyeliminować wywołanie metody.
Wywołanie metody nie jest obsługiwane, biorąc pod uwagę stan obiektu. Próbujesz wywołać element członkowski, którego funkcjonalność jest niedostępna ze względu na stan obiektu. Wyjątek można wyeliminować na jeden z trzech sposobów:
Znasz stan obiektu z wyprzedzeniem, ale wywołano nieobsługiwaną metodę lub właściwość. W takim przypadku wywołanie elementu członkowskiego jest błędem i można go wyeliminować.
Wiesz, że stan obiektu z wyprzedzeniem (zwykle z powodu utworzenia wystąpienia kodu), ale obiekt jest nieprawidłowo skonfigurowany. Poniższy przykład ilustruje ten problem. Tworzy obiekt tylko FileStream do odczytu, a następnie próbuje go zapisać.
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 wyeliminować wyjątek, upewniając się, że wystąpienie obiektu obsługuje funkcję, którą zamierzasz wykonać. W poniższym przykładzie rozwiązano problem obiektu tylko FileStream do odczytu, podając poprawne argumenty konstruktorowi FileStream.FileStream(String, FileMode, FileAccess) .
Nie znasz stanu obiektu z wyprzedzeniem, a obiekt nie obsługuje określonej operacji. W większości przypadków obiekt powinien zawierać właściwość lub metodę wskazującą, czy obsługuje określony zestaw operacji. Wyjątek można wyeliminować, sprawdzając wartość obiektu i wywołując element członkowski tylko wtedy, gdy jest to konieczne.
W poniższym przykładzie zdefiniowano metodę
DetectEncoding
, która zgłasza NotSupportedException wyjątek podczas próby odczytu od początku strumienia, który nie obsługuje dostępu do odczytu.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()
Wyjątek można wyeliminować, sprawdzając wartość FileStream.CanRead właściwości i zamykając metodę, jeśli strumień jest tylko do odczytu.
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
Powiązane typy wyjątków
Wyjątek jest ściśle związany z dwoma NotSupportedException innymi typami wyjątków;
-
Ten wyjątek jest zgłaszany, gdy można zaimplementować metodę, ale nie, ponieważ element członkowski zostanie zaimplementowany w nowszej wersji, składowy nie jest dostępny na określonej platformie lub składowa należy do klasy abstrakcyjnej, a klasa pochodna musi zapewnić implementację.
-
Ten wyjątek jest zgłaszany w scenariuszach, w których zazwyczaj jest możliwe, aby obiekt wykonał żądaną operację, a stan obiektu określa, czy można wykonać operację.
Uwagi dotyczące programu .NET Compact Framework
Podczas pracy z platformą .NET Compact Framework i używania funkcji P/Invoke w funkcji natywnej ten wyjątek może zostać zgłoszony, jeśli:
- Deklaracja w kodzie zarządzanym jest niepoprawna.
- Program .NET Compact Framework nie obsługuje tego, co próbujesz zrobić.
- Nazwy bibliotek DLL są mangled w eksporcie.
Jeśli zgłaszany NotSupportedException jest wyjątek, sprawdź:
- W przypadku wszelkich naruszeń ograniczeń P/Invoke programu .NET Compact Framework.
- W przypadku wszystkich argumentów, które wymagają wstępnie przydzielonej pamięci. Jeśli te istnieją, należy przekazać odwołanie do istniejącej zmiennej.
- Czy nazwy wyeksportowanych funkcji są poprawne. Można to zweryfikować za pomocą DumpBin.exe.
- To, że nie próbujesz przekazać zbyt wielu argumentów.