Класс System.NotSupportedException
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
NotSupportedException указывает, что реализация не существует для вызываемого метода или свойства.
NotSupportedException использует HRESULT COR_E_NOTSUPPORTED
, который имеет значение 0x80131515.
Список начальных значений свойств для экземпляра NotSupportedException, см. в разделе NotSupportedException конструкторы.
Создание исключения NotSupportedException
Вы можете вызвать NotSupportedException исключение в следующих случаях:
Вы реализуете интерфейс общего назначения и количество методов не имеют понятной реализации. Например, если вы создаете тип даты и времени, реализующего IConvertible интерфейс, вы создадите NotSupportedException исключение для большинства преобразований.
Вы унаследовали от абстрактного класса, требующего переопределения ряда методов. Однако вы готовы предоставить реализацию только для подмножества этих элементов. Для методов, которые вы решили не реализовать, можно выбрать исключение NotSupportedException.
Вы определяете тип общего назначения с состоянием, которое позволяет выполнять операции условно. Например, тип может быть только для чтения или записи. В этом случае:
Если объект доступен только для чтения, попытка назначить значения свойствам экземпляра или вызывать методы, изменяющие состояние экземпляра, должны вызывать NotSupportedException исключение.
Необходимо реализовать свойство, возвращающее значение, указывающее Boolean , доступна ли определенная функциональность. Например, для типа, который может быть доступным только для чтения или записи, можно реализовать
IsReadOnly
свойство, указывающее, доступен ли набор методов чтения и записи или недоступен.
Обработка исключения NotSupportedException
Исключение NotSupportedException указывает, что метод не имеет реализации и не должен вызывать его. Не следует обрабатывать исключение. Вместо этого, что следует сделать, зависит от причины исключения: отсутствует ли реализация или вызов члена не согласуется с целью объекта (например, вызов FileStream.Write метода только для чтения FileStream ).
Реализация не была предоставлена, так как операция не может быть выполнена значимым образом. Это обычное исключение при вызове методов объекта, предоставляющего реализации методов абстрактного базового класса или реализующего интерфейс общего назначения, и метод не имеет понятной реализации.
Например, Convert класс реализует IConvertible интерфейс, что означает, что он должен включать метод для преобразования каждого примитивного типа в любой другой примитивный тип. Однако многие из этих преобразований недоступны. В результате вызов Convert.ToBoolean(DateTime) метода, например, вызывает NotSupportedException исключение, поскольку преобразование между DateTime значением и Boolean значением невозможно.
Чтобы исключить исключение, следует исключить вызов метода.
Вызов метода не поддерживается, учитывая состояние объекта. Вы пытаетесь вызвать члена, функциональность которого недоступна из-за состояния объекта. Исключение можно исключить одним из трех способов:
Вы знаете состояние объекта заранее, но вы вызвали неподдерживаемый метод или свойство. В этом случае вызов члена является ошибкой, и ее можно устранить.
Вы знаете состояние объекта заранее (обычно потому, что код создал его), но объект настроен неправильно. В следующем примере показана эта проблема. Он создает объект только для 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.FileStream(String, FileMode, FileAccess) .
Состояние объекта заранее не известно, и объект не поддерживает определенную операцию. В большинстве случаев объект должен включать свойство или метод, указывающий, поддерживает ли он определенный набор операций. Исключение можно исключить, проверка значение объекта и вызов элемента только в случае необходимости.
В следующем примере определяется
DetectEncoding
метод, который создает NotSupportedException исключение при попытке считывания с начала потока, который не поддерживает доступ на чтение.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 тесно связано с двумя другими типами исключений;
-
Это исключение возникает, если метод может быть реализован, но не является, либо потому, что член будет реализован в более поздней версии, член недоступен на определенной платформе, либо член принадлежит абстрактному классу, а производный класс должен предоставить реализацию.
-
Это исключение возникает в сценариях, в которых, как правило, объект может выполнять запрошенную операцию, и состояние объекта определяет, может ли выполняться операция.
Заметки .NET Compact Framework
При работе с .NET Compact Framework и использованием P/Invoke в собственной функции это исключение может быть вызвано, если:
- объявление в управляемом коде неправильно;
- Платформа .NET Compact Framework не поддерживает то, что вы пытаетесь сделать.
- имена библиотек DLL не подходят для экспорта.
NotSupportedException Если создается исключение, проверка:
- Для любых нарушений ограничений .NET Compact Framework P/Invoke.
- на наличие любых аргументов, требующих предварительного выделения памяти. Если они существуют, следует передавать ссылку на существующую переменную;
- что имена экспортированных функций заданы верно. Это можно проверить с помощью DumpBin.exe.
- что нет попыток передачи слишком большого числа аргументов.