Classe System.NotSupportedException
Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.
NotSupportedException indique qu’aucune implémentation n’existe pour une méthode ou une propriété appelée.
NotSupportedException utilise le HRESULT COR_E_NOTSUPPORTED
, qui a la valeur 0x80131515.
Pour obtenir la liste des valeurs initiales des propriétés d’une instance de NotSupportedException, consultez le NotSupportedException constructeurs.
Déclencher une exception NotSupportedException
Vous pouvez envisager de déclencher une exception NotSupportedException dans les cas suivants :
Vous implémentez une interface à usage général et le nombre de méthodes n’ont aucune implémentation significative. Par exemple, si vous créez un type de date et d’heure qui implémente l’interface IConvertible, vous déclencheriez une exception NotSupportedException pour la plupart des conversions.
Vous avez hérité d’une classe abstraite qui exige que vous substituiez un certain nombre de méthodes. Toutefois, vous êtes seulement prêt à fournir une implémentation pour un sous-ensemble de celles-ci. Pour les méthodes que vous décidez de ne pas implémenter, vous pouvez choisir de déclencher une NotSupportedException.
Vous définissez un type à usage général avec un état qui permet des opérations de manière conditionnelle. Par exemple, votre type peut être en lecture seule ou en lecture-écriture. Dans ce cas :
Si l’objet est en lecture seule, toute tentative d’affectation de valeurs aux propriétés d’une instance ou d’appel de méthodes qui modifient l’état de l’instance doit déclencher une exception NotSupportedException.
Vous devez implémenter une propriété qui retourne une valeur Boolean qui indique si des fonctionnalités particulières sont disponibles. Par exemple, pour un type qui peut être en lecture seule ou en lecture-écriture, vous pouvez implémenter une propriété
IsReadOnly
qui indique si l’ensemble de méthodes en lecture-écriture est disponible ou non.
Gérer une exception NotSupportedException
L’exception NotSupportedException indique qu’une méthode n’a pas d’implémentation et que vous ne devriez pas l’appeler. Vous ne devriez pas gérer l’exception. Au lieu de cela, ce que vous devriez faire dépend de la cause de l’exception : si une implémentation est complètement absente ou si l’appel de membre est incohérent avec le but d’un objet (par exemple, un appel à la méthode FileStream.Write sur un objet FileStream en lecture seule).
Une implémentation n’a pas été fournie, car l’opération ne peut pas être effectuée de manière significative. C’est une exception courante lorsque vous appelez des méthodes sur un objet qui fournit des implémentations pour les méthodes d’une classe de base abstraite, ou qui implémente une interface à usage général, et que la méthode n’a aucune implémentation significative.
Par exemple, la classe Convert implémente l’interface IConvertible, ce qui signifie qu’elle doit inclure une méthode pour convertir chaque type primitif en chaque autre type primitif. Toutefois, la plupart de ces conversions ne sont pas possibles. Par conséquent, un appel à la méthode Convert.ToBoolean(DateTime), par exemple, déclenche une exception NotSupportedException, car il n’existe aucune conversion possible entre une DateTime et une valeur de Boolean
Pour éliminer l’exception, vous devez éliminer l’appel de méthode.
L’appel de méthode n’est pas pris en charge en fonction de l’état de l’objet. Vous tentez d’appeler un membre dont la fonctionnalité n’est pas disponible en raison de l’état de l’objet. Vous pouvez éliminer l’exception de trois façons :
Vous connaissez l’état de l’objet à l’avance, mais vous avez appelé une méthode ou une propriété non prise en charge. Dans ce cas, l’appel de membre est une erreur et vous pouvez l’éliminer.
Vous connaissez l’état de l’objet à l’avance (généralement parce que votre code l’a instancié), mais l’objet est mal configuré. L’exemple suivant illustre ce problème. Il crée un objet FileStream en lecture seule, puis tente d’y écrire.
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 élimine l’exception en veillant à ce que l’objet instancié prenne en charge les fonctionnalités que vous envisagez. L’exemple suivant résout le problème de l’objet FileStream en lecture seule en fournissant les arguments appropriés au constructeur FileStream.FileStream(String, FileMode, FileAccess).
Vous ne connaissez pas l’état de l’objet à l’avance et l’objet ne prend pas en charge une opération particulière. Dans la plupart des cas, l’objet doit inclure une propriété ou une méthode qui indique s’il prend en charge un ensemble particulier d’opérations. Vous pouvez éliminer l’exception en vérifiant la valeur de l’objet et en appelant le membre uniquement si nécessaire.
L’exemple suivant définit une méthode
DetectEncoding
qui déclenche une exception NotSupportedException lorsqu’elle tente de lire à partir du début d’un flux qui ne prend pas en charge l’accès en lecture.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()
Vous pouvez éliminer l’exception en examinant la valeur de la propriété FileStream.CanRead et en quittant la méthode si le flux est en lecture seule.
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
Types d’exceptions associés
L’exception NotSupportedException est étroitement liée à deux autres types d’exceptions ;
-
Cette exception est déclenchée lorsqu’une méthode peut être implémentée, mais ne l'est pas, soit parce que le membre sera implémenté dans une version ultérieure, le membre n’est pas disponible sur une plateforme particulière, ou le membre appartient à une classe abstraite et une classe dérivée doit fournir une implémentation.
-
Cette exception est déclenchée dans les scénarios dans lesquels il est généralement possible que l’objet effectue l’opération demandée, et l’état de l’objet détermine si l’opération peut être effectuée.
Notes .NET Compact Framework
Lorsque vous utilisez .NET Compact Framework et P/Invoke sur une fonction native, cette exception peut être déclenchée si :
- la déclaration dans le code managé est incorrecte ;
- Le .NET Compact Framework ne prend pas en charge l’opération que vous tentez d'effectuer.
- les noms de DLL sont tronqués lors de l'exportation.
Si une exception NotSupportedException est déclenchée, vérifiez :
- Pour toute violation des restrictions P/Invoke du .NET Compact Framework.
- Recherchez tous les arguments qui requièrent de la mémoire pré-allouée. Si vous en trouvez, vous devez passer une référence à une variable existante.
- Vérifiez que les noms des fonctions exportées sont corrects. Cette vérification peut être réalisée à l'aide de DumpBin.exe.
- Vérifiez que vous n'essayez pas de passer un trop grand nombre d'arguments.