Compartilhar via


Classe System.NotSupportedException

Este artigo fornece comentários complementares à documentação de referência para esta API.

NotSupportedException indica que não existe nenhuma implementação para um método ou propriedade invocado.

NotSupportedException usa o HRESULT COR_E_NOTSUPPORTED, que tem o valor 0x80131515.

Para obter uma lista de valores de propriedade iniciais de uma instância de NotSupportedException, consulte os construtores de NotSupportedException.

Lançar uma exceção do tipo NotSupportedException

Você pode considerar gerar uma exceção NotSupportedException nos seguintes casos:

  • Você está implementando uma interface de uso geral e o número de métodos não tem nenhuma implementação significativa. Por exemplo, se você estiver criando um tipo de data e hora que implemente a interface IConvertible, você lançaria uma exceção NotSupportedException para a maioria das conversões.

  • Você herdou de uma classe abstrata que exige a substituição de vários métodos. No entanto, você só está preparado para fornecer uma implementação para um subconjunto deles. Para os métodos que você decidir não implementar, você pode optar por gerar um NotSupportedException.

  • Você está definindo um tipo de uso geral com um estado que habilita as operações condicionalmente. Por exemplo, seu tipo pode ser somente leitura ou leitura e gravação. Nesse caso:

    • Se o objeto for somente leitura, a tentativa de atribuir valores às propriedades de uma instância ou métodos de chamada que modificam o estado da instância deverá gerar uma NotSupportedException exceção.

    • Você deve implementar uma propriedade que retorna um Boolean valor que indica se uma funcionalidade específica está disponível. Por exemplo, para um tipo que pode ser somente leitura ou leitura/gravação, você poderia implementar uma propriedade IsReadOnly que indica se o conjunto de métodos de leitura/gravação está disponível ou não.

Tratar uma exceção NotSupportedException

A NotSupportedException exceção indica que um método não tem implementação e que você não deve chamá-lo. Você não deve lidar com a exceção. Em vez disso, o que você deve fazer depende da causa da exceção: se uma implementação está completamente ausente ou se a invocação de membro é inconsistente com a finalidade de um objeto (como uma chamada ao método FileStream.Write em um objeto de leitura FileStream somente).

Uma implementação não foi fornecida porque a operação não pode ser executada de forma significativa. Essa é uma exceção comum quando você está chamando métodos em um objeto que fornece implementações para os métodos de uma classe base abstrata ou que implementa uma interface de uso geral e o método não tem nenhuma implementação significativa.

Por exemplo, a classe Convert implementa a interface IConvertible, o que significa que ela deve incluir um método para converter cada tipo primitivo em todos os outros tipos primitivos. Muitas dessas conversões, no entanto, não são possíveis. Como resultado, uma chamada para o Convert.ToBoolean(DateTime) método, por exemplo, gera uma NotSupportedException exceção porque não há nenhuma conversão possível entre um DateTime e um Boolean valor

Para eliminar a exceção, você deve eliminar a chamada de método.

Não há suporte para a chamada de método dado o estado do objeto. Você está tentando invocar um membro cuja funcionalidade está indisponível devido ao estado do objeto. Você pode eliminar a exceção de uma das três maneiras:

  • Você sabe o estado do objeto com antecedência, mas invocou um método ou propriedade sem suporte. Nesse caso, a invocação de membro é um erro e você pode eliminá-la.

  • Você sabe o estado do objeto com antecedência (geralmente porque seu código o instanciou), mas o objeto está configurado incorretamente. O exemplo a seguir ilustra esse problema. Ele cria um objeto FileStream somente leitura e, em seguida, tenta gravar nele.

    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()
    

    Você pode eliminar a exceção garantindo que o objeto instanciado dê suporte à funcionalidade que você pretende. O exemplo a seguir resolve o problema do objeto FileStream só para leitura, fornecendo os argumentos corretos para o construtor FileStream.FileStream(String, FileMode, FileAccess).

  • Você não sabe o estado do objeto com antecedência e o objeto não dá suporte a uma operação específica. Na maioria dos casos, o objeto deve incluir uma propriedade ou método que indique se ele dá suporte a um determinado conjunto de operações. Você pode eliminar a exceção verificando o valor do objeto e invocando o membro somente se apropriado.

    O exemplo a seguir define um DetectEncoding método que gera uma NotSupportedException exceção quando tenta ler desde o início de um fluxo que não dá suporte ao acesso de leitura.

    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()
    

    Você pode eliminar a exceção examinando o valor da propriedade FileStream.CanRead e saindo do método se o fluxo for de leitura somente.

        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
    

A NotSupportedException exceção está intimamente relacionada a dois outros tipos de exceção;

  • NotImplementedException

    Essa exceção é gerada quando um método pode ser implementado, mas não é, porque o membro será implementado em uma versão posterior, o membro não está disponível em uma plataforma específica ou o membro pertence a uma classe abstrata e uma classe derivada deve fornecer uma implementação.

  • InvalidOperationException

    Essa exceção é gerada em cenários em que geralmente, às vezes, é possível que o objeto execute a operação solicitada e o estado do objeto determina se a operação pode ser executada.

Notas do .NET Compact Framework

Ao trabalhar com o .NET Compact Framework e usar P/Invoke em uma função nativa, essa exceção poderá ser gerada se:

  • A declaração no código gerenciado está incorreta.
  • O .NET Compact Framework não dá suporte ao que você está tentando fazer.
  • Os nomes de DLL são danificados na exportação.

Se uma NotSupportedException exceção for gerada, verifique:

  • Para quaisquer violações das restrições de P/Invoke do .NET Compact Framework.
  • Para quaisquer argumentos que exijam memória pré-alocada. Se existirem, você deverá passar uma referência para uma variável existente.
  • Que os nomes das funções exportadas estão corretos. Isso pode ser verificado com DumpBin.exe.
  • Certifique-se de que você não está tentando passar argumentos demais.