Share via


Alterações interruptivas nas bibliotecas principais do .NET Core 1.0 a 3.0

As principais bibliotecas .NET fornecem os primitivos e outros tipos gerais usados pelo .NET Core.

As seguintes alterações interruptivas estão documentadas nesta página:

Alteração interruptiva Versão introduzida
Passar GroupCollection para métodos de extensão tomando IEnumerable<T> requer desambiguidade .NET Core 3.0
APIs que relatam a versão agora relatam o produto e não a versão do arquivo .NET Core 3.0
As instâncias personalizadas do EncoderFallbackBuffer não podem fazer fallback recursivamente .NET Core 3.0
Alterações de comportamento de formatação e análise de ponto flutuante .NET Core 3.0
As operações de análise de ponto flutuante não falham mais ou lançam uma OverflowException .NET Core 3.0
InvalidAsynchronousStateException movido para outro assembly .NET Core 3.0
Substituir sequências de bytes UTF-8 mal formadas segue as diretrizes do Unicode .NET Core 3.0
TypeDescriptionProviderAttribute movido para outro assembly .NET Core 3.0
ZipArchiveEntry não lida mais com arquivos com tamanhos de entrada inconsistentes .NET Core 3.0
FieldInfo.SetValue lança exceção para campos estáticos somente init .NET Core 3.0
AS APIs de caminho não geram uma exceção para caracteres inválidos .NET Core 2.1
Campos privados adicionados a tipos de struct internos .NET Core 2.1
Alteração no valor padrão de UseShellExecute .NET Core 2.1
Versões do OpenSSL no macOS .NET Core 2.1
UnauthorizedAccessException gerada por FileSystemInfo.Attributes .NET Core 1.0
Não há suporte para o tratamento de exceções de estado de processo corrompido .NET Core 1.0
As propriedades do UriBuilder não acrescentam mais caracteres à esquerda .NET Core 1.0
Process.StartInfo gera uma InvalidOperationException para processos que você não iniciou .NET Core 1.0

.NET Core 3.0

Passar GroupCollection para métodos de extensão tomando IEnumerable<T> requer desambiguidade

Ao chamar um método de extensão que usa IEnumerable<T> ou GroupCollection, você deve desambiguar o tipo usando uma conversão.

Descrição das alterações

Do .NET Core 3.0 em diante, System.Text.RegularExpressions.GroupCollection implementa IEnumerable<KeyValuePair<String,Group>> além dos outros tipos implementados, incluindo IEnumerable<Group>. Isso resulta em ambiguidade ao chamar um método de extensão que usa um IEnumerable<T>. Se você chamar esse método de extensão em uma instância GroupCollection, por exemplo, Enumerable.Count, verá o seguinte erro do compilador:

CS1061: 'GroupCollection' não contém uma definição para "{1}" e não foi possível encontrar nenhum método de extensão "{1}" que aceite um primeiro argumento do tipo ‘{0}’ (você está se esquecendo de usar uma diretiva ou uma referência de assembly?)

Nas versões anteriores do .NET, não havia ambiguidade nem erro do compilador.

Versão introduzida

3.0

Motivo da alteração

Essa foi uma alteração interruptiva involuntária. Pois tem sido assim há algum tempo, não planejamos revertê-la. Além disso, tal alteração seria, por si só, interruptiva.

Para instâncias GroupCollection, desambiguar chamadas para métodos de extensão que aceitam IEnumerable<T> com uma conversão.

// Without a cast - causes CS1061.
match.Groups.Count(_ => true)

// With a disambiguating cast.
((IEnumerable<Group>)m.Groups).Count(_ => true);

Categoria

Bibliotecas principais do .NET

APIs afetadas

Qualquer método de extensão que aceite IEnumerable<T> é afetado. Por exemplo:


APIs que relatam a versão agora relatam o produto e não a versão do arquivo

Muitas das APIs que retornam versões no .NET Core agora retornam a versão do produto em vez da versão do arquivo.

Descrição das alterações

No .NET Core 2.2, e em versões anteriores, métodos como Environment.Version, RuntimeInformation.FrameworkDescription e a caixa de diálogo propriedades do arquivo para assemblies do .NET Core refletem a versão do arquivo. Do .NET Core 3.0 em diante, eles refletem a versão do produto.

A figura a seguir ilustra a diferença nas informações de versão do assembly System.Runtime.dll para o .NET Core 2.2 (à esquerda) e o .NET Core 3.0 (à direita), conforme exibido pela caixa de diálogo propriedades do arquivo do Windows Explorer.

Difference in product version information

Versão introduzida

3.0

Nenhum. Essa alteração deve tornar a detecção de versão intuitiva em vez de obtusa.

Categoria

Bibliotecas principais do .NET

APIs afetadas


As instâncias personalizadas do EncoderFallbackBuffer não podem fazer fallback recursivamente

As instâncias personalizadas EncoderFallbackBuffer não podem fazer fallback recursivamente. A implementação de EncoderFallbackBuffer.GetNextChar() deve resultar em uma sequência de caracteres que é conversível para a codificação de destino. Caso contrário, uma exceção ocorrerá.

Descrição das alterações

Durante uma operação de transcodificação de caractere a byte, o runtime detecta sequências UTF-16 mal formadas ou não reversíveis e fornece esses caracteres para o método EncoderFallbackBuffer.Fallback. O método Fallback determina quais caracteres devem ser substituídos pelos dados não reversíveis originais e esses caracteres são drenados chamando EncoderFallbackBuffer.GetNextChar em um loop.

Em seguida, o runtime tenta transcodificar esses caracteres de substituição para a codificação de destino. Se essa operação for bem-sucedida, o runtime continuará a transcodificação de onde parou na cadeia de caracteres de entrada original.

Anteriormente, as implementações personalizadas de EncoderFallbackBuffer.GetNextChar() podem retornar sequências de caracteres que não são conversíveis para a codificação de destino. Se os caracteres substituídos não puderem ser transcodificados para a codificação de destino, o runtime invocará o método EncoderFallbackBuffer.Fallback mais uma vez com os caracteres de substituição, esperando que o método EncoderFallbackBuffer.GetNextChar() retorne uma nova sequência de substituição. Esse processo continua até que o runtime eventualmente veja uma substituição conversível bem formada ou até que uma contagem máxima de recursão seja atingida.

Do .NET Core 3.0 em diante, as implementações personalizadas de EncoderFallbackBuffer.GetNextChar() devem retornar sequências de caracteres conversíveis para a codificação de destino. Se os caracteres substituídos não puderem ser transcodificados para a codificação de destino, um ArgumentException será gerado. O runtime não fará mais chamadas recursivas na instância EncoderFallbackBuffer.

Esse comportamento só se aplica quando todas as três condições seguintes são atendidas:

  • O runtime detecta uma sequência UTF-16 mal formada ou uma sequência UTF-16 que não pode ser convertida na codificação de destino.
  • Um EncoderFallback personalizado foi especificado.
  • As tentativas personalizadas EncoderFallback de substituir uma nova sequência UTF-16 mal formada ou não reversível.

Versão introduzida

3.0

A maioria dos desenvolvedores não precisa tomar nenhuma ação.

Se um aplicativo usa classes EncoderFallback e EncoderFallbackBuffer personalizadas, verifique se a implementação de EncoderFallbackBuffer.Fallback popula o buffer de fallback com os dados UTF-16 bem formados que são diretamente conversíveis para a codificação de destino, quando o método Fallback é invocado pela primeira vez pelo runtime.

Categoria

Bibliotecas principais do .NET

APIs afetadas


Alterações de comportamento de formatação e análise de ponto flutuante

O comportamento de análise e formatação de ponto flutuante (por tipos Double e Single) agora é compatível com IEEE. Isso garante que o comportamento de tipos de ponto flutuante no .NET corresponda ao de outras linguagens compatíveis com IEEE. Por exemplo, double.Parse("SomeLiteral") sempre deve corresponder ao que o C# produz para double x = SomeLiteral.

Descrição das alterações

No .NET Core 2.2 e versões anteriores, a formatação com Double.ToString e Single.ToString e a análise com Double.Parse, Double.TryParse, Single.Parse e Single.TryParse não são compatíveis com IEEE. Como resultado, é impossível garantir que um valor seja arredondado com qualquer cadeia de caracteres de formato padrão ou personalizado com suporte. Para algumas entradas, a tentativa de analisar um valor formatado pode falhar e, para outras, o valor analisado não é igual ao valor original.

Do .NET Core 3.0 em diante, as operações de análise e formatação de ponto flutuante são compatíveis com o IEEE 754.

A tabela a seguir mostra dois snippets de código e como a saída é alterada entre o .NET Core 2.2 e o .NET Core 3.1.

Snippet de código Saída no .NET Core 2.2 Saída no .NET Core 3.1
Console.WriteLine((-0.0).ToString()); 0 -0
var value = -3.123456789123456789;
Console.WriteLine(value == double.Parse(value.ToString()));
False True

Para obter mais informações, confira a postagem no blog Aprimoramentos de formatação e análise de ponto flutuante no .NET Core 3.0.

Versão introduzida

3.0

O impacto potencial na seção de código existente das melhorias de análise e formatação de ponto flutuante na postagem de blog do .NET Core 3.0 sugere algumas alterações que você pode fazer ao seu código se quiser manter o comportamento anterior.

  • Para algumas diferenças na formatação, você pode obter um comportamento equivalente ao comportamento anterior especificando uma cadeia de caracteres de formato diferente.
  • Para diferenças na análise, não há mecanismo para voltar ao comportamento anterior.

Categoria

Bibliotecas principais do .NET

APIs afetadas


As operações de análise de ponto flutuante não falham mais ou lançam uma OverflowException

Os métodos de análise de ponto flutuante não lançam mais um OverflowException ou retornam false quando analisam uma cadeia de caracteres cujo valor numérico está fora do intervalo do tipo Single ou Double ponto flutuante.

Descrição das alterações

No .NET Core 2.2 e em versões anteriores, os métodos Double.Parse e Single.Parse lançam OverflowException para valores que estão fora do intervalo de seu respectivo tipo. Os métodos Double.TryParse e Single.TryParse retornam false para as representações de cadeia de caracteres de valores numéricos fora do intervalo.

Do .NET Core 3.0 em diante, os métodos Double.Parse, Double.TryParse, Single.Parse e Single.TryParse não falham mais ao analisar cadeias de caracteres numéricas fora do intervalo. Em vez disso, os métodos de análise Double retornam Double.PositiveInfinity, para valores que excedem Double.MaxValue, e retornam Double.NegativeInfinity, para valores menores que Double.MinValue. Similarmente, os métodos de análise Single retornam Single.PositiveInfinity, para valores que excedem Single.MaxValue, e retornam Single.NegativeInfinity, para valores menores que Single.MinValue.

Essa alteração foi feita para melhorar a conformidade do IEEE 754:2008.

Versão introduzida

3.0

Essa alteração pode afetar seu código de duas maneiras:

  • Seu código depende do manipulador para a execução OverflowException quando ocorrer um estouro. Nesse caso, você deve remover a instrução catch e colocar qualquer código necessário em uma instrução If que testa se Double.IsInfinity ou Single.IsInfinity é true.

  • Seu código pressupõe que os valores de ponto flutuante não são Infinity. Nesse caso, você deve adicionar o código necessário para verificar se há valores de ponto flutuante PositiveInfinity e NegativeInfinity.

Categoria

Bibliotecas principais do .NET

APIs afetadas


InvalidAsynchronousStateException movido para outro assembly

A classe InvalidAsynchronousStateException foi movida.

Descrição das alterações

No .NET Core 2.2 e versões anteriores, a classe InvalidAsynchronousStateException é encontrada no assembly System.ComponentModel.TypeConverter.

Do .NET Core 3.0 em diante, ele é encontrado no assembly System.ComponentModel.Primitives.

Versão introduzida

3.0

Essa alteração afeta apenas os aplicativos que usam reflexão para carregar InvalidAsynchronousStateException chamando um método como Assembly.GetType ou uma sobrecarga de Activator.CreateInstance que pressupõe que o tipo esteja em um assembly específico. Se esse for o caso, atualize o assembly referenciado na chamada de método para refletir o novo local do assembly do tipo.

Categoria

Bibliotecas principais do .NET

APIs afetadas

Nenhum.


Substituir sequências de bytes UTF-8 mal formadas segue as diretrizes do Unicode

Quando a classe UTF8Encoding encontra uma sequência de bytes UTF-8 mal formada durante uma operação de transcodificação de byte para caractere, ela substitui essa sequência por um caractere ' (U+FFFD REPLACEMENT CHARACTER) na cadeia de caracteres de saída. O .NET Core 3.0 é diferente das versões anteriores do .NET Core e do .NET Framework seguindo a melhor prática de unicode para executar essa substituição durante a operação de transcodificação.

Isso faz parte de um esforço maior para melhorar a manipulação do UTF-8 em todo o .NET, inclusive pelos novos tipos System.Text.Unicode.Utf8 e System.Text.Rune. O tipo UTF8Encoding recebeu uma mecânica aprimorada de tratamento de erros para que produza uma saída consistente com os tipos recém-introduzidos.

Descrição das alterações

Do .NET Core 3.0 em diante, ao transcodificar bytes para caracteres, a classe UTF8Encoding executa a substituição de caracteres com base nas práticas recomendadas Unicode. O mecanismo de substituição usado é descrito pelo Unicode Standard, Versão 12.0, S. 3.9 (PDF) no título intitulado Substituição U+FFFD de Subpartes Máximas.

Esse comportamento se aplica quando a sequência de bytes de entrada contém dados UTF-8 mal formados. Além disso, se a instância UTF8Encoding tiver sido construída com throwOnInvalidBytes: true, a instância UTF8Encoding continuará a ser lançada na entrada inválida em vez de executar a substituição U+FFFD. Para obter mais informações sobre o construtor UTF8Encoding, confira UTF8Encoding(Boolean, Boolean).

A seguinte tabela ilustra o impacto dessa alteração com uma entrada inválida de 3 bytes:

Entrada de 3 bytes mal formada Saída antes do .NET Core 3.0 Começando com o SDK do .NET Core 3.0
[ ED A0 90 ] [ FFFD FFFD ] (saída de 2 caracteres) [ FFFD FFFD FFFD ] (saída de 3 caracteres)

A saída de 3 caracteres é a preferencial, de acordo com a Tabela 3-9 do PDF Standard Unicode vinculado anteriormente.

Versão introduzida

3.0

Nenhuma ação é necessária por parte do desenvolvedor.

Categoria

Bibliotecas principais do .NET

APIs afetadas


TypeDescriptionProviderAttribute movido para outro assembly

A classe TypeDescriptionProviderAttribute foi movida.

Descrição das alterações

No .NET Core 2.2 e versões anteriores, a classe TypeDescriptionProviderAttribute é encontrada no assembly System.ComponentModel.TypeConverter .

Do .NET Core 3.0 em diante, ela é encontrada no assembly System.ObjectModel.

Versão introduzida

3.0

Essa alteração afeta apenas os aplicativos que usam reflexão para carregar o tipo TypeDescriptionProviderAttribute chamando um método como Assembly.GetType ou uma sobrecarga de Activator.CreateInstance que pressupõe que o tipo esteja em um assembly específico. Se esse for o caso, o assembly referenciado na chamada de método deverá ser atualizado para refletir o novo local do assembly do tipo.

Categoria

Windows Forms

APIs afetadas

Nenhum.


ZipArchiveEntry não lida mais com arquivos com tamanhos de entrada inconsistentes

Os arquivos zip listam o tamanho compactado e o tamanho não compactado no diretório central e no cabeçalho local. Os próprios dados de entrada também indicam seu tamanho. No .NET Core 2.2 e em versões anteriores, esses valores nunca foram verificados quanto à consistência. Do .NET Core 3.0 em diante, eles serão verificados.

Descrição das alterações

No .NET Core 2.2 e nas versões anteriores, ZipArchiveEntry.Open() é bem-sucedido mesmo que o cabeçalho local discordou do cabeçalho central do arquivo zip. Os dados são descompactados até que o final do fluxo compactado seja atingido, mesmo que seu comprimento exceda o tamanho do arquivo não compactado listado no diretório central/cabeçalho local.

Do .NET Core 3.0 em diante, o método ZipArchiveEntry.Open() verifica se o cabeçalho local e o cabeçalho central concordam em tamanhos compactados e não compactados de uma entrada. Se não o fizerem, o método vai gerar InvalidDataException, se o cabeçalho local do arquivo morto e/ou descritor de dados listar os tamanhos que discordam do diretório central do arquivo zip. Ao ler uma entrada, os dados descompactados são truncados para o tamanho do arquivo não compactado listado no cabeçalho.

Essa alteração foi feita para garantir que um valor ZipArchiveEntry representa corretamente o tamanho de seus dados e que somente essa quantidade de dados seja lida.

Versão introduzida

3.0

Reempacotar qualquer arquivo zip que exponha esses problemas.

Categoria

Bibliotecas principais do .NET

APIs afetadas


FieldInfo.SetValue lança exceção para campos estáticos somente init

Do .NET Core 3.0 em diante, uma exceção é gerada quando você tenta definir um valor em um campo estático InitOnly chamando System.Reflection.FieldInfo.SetValue.

Descrição das alterações

Em .NET Framework e versões do .NET Core anteriores à 3.0, você pode definir o valor de um campo estático que é constante depois que ele é inicializado (somente leitura em C#) chamando System.Reflection.FieldInfo.SetValue. No entanto, definir esse campo dessa forma resultou em um comportamento imprevisível com base na estrutura de destino e nas configurações de otimização.

No .NET Core 3.0 e versões posteriores, quando você chama SetValue em um campo estático InitOnly uma exceção System.FieldAccessException é lançada.

Dica

Um campo InitOnly é aquele que só pode ser definido no momento em que é declarado ou no construtor da classe que contém. Em outras palavras, ele é constante depois de inicializado.

Versão introduzida

3.0

Inicialize campos estáticos InitOnly em um construtor estático. Isso se aplica a tipos dinâmicos e não dinâmicos.

Como alternativa, você pode remover o atributo do campo FieldAttributes.InitOnly e, em seguida, chamar FieldInfo.SetValue.

Categoria

Bibliotecas principais do .NET

APIs afetadas


.NET Core 2.1

AS APIs de caminho não geram uma exceção para caracteres inválidos

As APIs que envolvem caminhos de arquivo não validam mais caracteres de caminho nem geram ArgumentException quando um caractere inválido é encontrado.

Descrição das alterações

No .NET Framework e no .NET Core 1.0 – 2.0, os métodos listados na seção APIs afetadas geram ArgumentException quando o argumento de caminho contém um caractere de caminho inválido. Do .NET Core 2.1 em diante, esses métodos não verificam mais se há caracteres de caminho inválidos nem geram uma exceção quando um caractere inválido é encontrado.

Motivo da alteração

A validação agressiva de caracteres de caminho bloqueia alguns cenários multiplataforma. Essa alteração foi introduzida para que o .NET não tente replicar nem prever o resultado das chamadas à API do sistema operacional. Para obter mais informações, confira a postagem no blog Novidade sobre o System.IO no .NET Core 2.1.

Versão introduzida

.NET Core 2.1

Se o código depende dessas APIs para verificar se há caracteres inválidos, você pode adicionar uma chamada a Path.GetInvalidPathChars.

APIs afetadas

Confira também


Campos privados adicionados a tipos de struct internos

Campos privados foram adicionados a determinados tipos de struct em assemblies de referência. Como resultado, em C#, sempre é necessário criar uma instância desses tipos de struct usando o operador new ou o literal padrão.

Descrição das alterações

No .NET Core 2.0 e nas versões anteriores, era possível criar uma instância de alguns tipos de struct fornecidos, por exemplo, ConsoleKeyInfo, sem usar o operador new ou o literal padrão em C#. Isso ocorria porque os assemblies de referência usados pelo compilador C# não continham os campos privados dos structs. Todos os campos privados de tipos de struct do .NET são adicionados aos assemblies de referência do .NET Core 2.1 em diante.

Por exemplo, o seguinte código C# é compilado no .NET Core 2.0, mas não no .NET Core 2.1:

ConsoleKeyInfo key;    // Struct type

if (key.ToString() == "y")
{
    Console.WriteLine("Yes!");
}

No .NET Core 2.1, o código anterior resultava no seguinte erro do compilador: CS0165 – Uso da variável local não atribuída 'key'

Versão introduzida

2.1

Crie instâncias de tipos de struct usando o operador new ou o literal padrão.

Por exemplo:

ConsoleKeyInfo key = new ConsoleKeyInfo();    // Struct type.

if (key.ToString() == "y")
    Console.WriteLine("Yes!");
ConsoleKeyInfo key = default;    // Struct type.

if (key.ToString() == "y")
    Console.WriteLine("Yes!");

Categoria

Bibliotecas principais do .NET

APIs afetadas


Alteração no valor padrão de UseShellExecute

ProcessStartInfo.UseShellExecute tem um valor padrão de false no .NET Core. No .NET Framework, o valor padrão é true.

Descrição das alterações

Process.Start permite iniciar um aplicativo diretamente, por exemplo, com um código como Process.Start("mspaint.exe"), que inicia o Paint. Ele também permite que você inicie indiretamente um aplicativo associado quando ProcessStartInfo.UseShellExecute está definido como true. No .NET Framework, o valor padrão de ProcessStartInfo.UseShellExecute é true, o que significa que um código como Process.Start("mytextfile.txt") iniciará o Bloco de notas se você associar arquivos .txt com esse editor. Para impedir a inicialização indireta de um aplicativo no .NET Framework, defina ProcessStartInfo.UseShellExecute explicitamente como false. No .NET Core, o valor padrão de ProcessStartInfo.UseShellExecute é false. Isso significa que, por padrão, os aplicativos associados não são iniciados quando você chama Process.Start.

As seguintes propriedades em System.Diagnostics.ProcessStartInfo só são funcionais quandoProcessStartInfo.UseShellExecute é true:

Essa alteração foi introduzida no .NET Core por motivos de desempenho. Normalmente, Process.Start é usado para iniciar um aplicativo diretamente. A inicialização direta um aplicativo não precisa envolver o shell do Windows e gerar um custo de desempenho associado. Para acelerar esse caso padrão, o .NET Core altera o valor padrão de ProcessStartInfo.UseShellExecutepara false. Você poderá aceitar o caminho mais lento se precisar.

Versão introduzida

2.1

Observação

Em versões anteriores do .NET Core, UseShellExecute não era implementado para o Windows.

Se o aplicativo depender do comportamento antigo, chame Process.Start(ProcessStartInfo) com UseShellExecute definido como true no objeto ProcessStartInfo.

Categoria

Bibliotecas principais do .NET

APIs afetadas


Versões do OpenSSL no macOS

O .NET Core 3.0 e os runtimes posteriores no macOS agora preferem as versões do OpenSSL 1.1.x a 1.0.x para os tipos AesCcm, AesGcm, DSAOpenSsl, ECDiffieHellmanOpenSsl, ECDsaOpenSsl, RSAOpenSsl e SafeEvpPKeyHandle.

O runtime do .NET Core 2.1 agora dá suporte a versões do OpenSSL 1.1.x, mas ainda prefere as versões do OpenSSL 1.0.x.

Descrição das alterações

Antes, o runtime do .NET Core usava as versões do OpenSSL 1.0.x no macOS para tipos que interagiam com o OpenSSL. A versão mais recente do OpenSSL 1.0.x, que é a OpenSSL 1.0.2, agora está sem suporte. Para manter os tipos que usam o OpenSSL em versões com suporte do OpenSSL, os runtimes do .NET Core 3.0 e posteriores agora usam versões mais recentes do OpenSSL no macOS.

Com essa alteração, o comportamento dos runtimes do .NET Core no macOS é o seguinte:

  • Os runtimes do .NET Core 3.0 e de versões posteriores usam o OpenSSL 1.1.x, se disponível, e retornam ao OpenSSL 1.0.x somente quando não há nenhuma versão 1.1.x disponível.

    Para chamadores que usam os tipos de interoperabilidade do OpenSSL com P/Invokes personalizados, siga as diretrizes nas observações de SafeEvpPKeyHandle.OpenSslVersion. O aplicativo poderá falhar se você não verificar o valor de OpenSslVersion.

  • O runtime do .NET Core 2.1 usa o OpenSSL 1.0.x, se disponível, e retorna ao OpenSSL 1.1.x quando não há nenhuma versão 1.0.x disponível.

    O runtime 2.1 prefere a versão anterior do OpenSSL porque a propriedade SafeEvpPKeyHandle.OpenSslVersion não existe no .NET Core 2.1, portanto, a versão do OpenSSL não pode ser determinada com confiança em tempo de execução.

Versão introduzida

  • .NET Core 2.1.16
  • .NET Core 3.0.3
  • .NET Core 3.1.2

Categoria

Bibliotecas principais do .NET

APIs afetadas


.NET Core 1.0

UnauthorizedAccessException gerada por FileSystemInfo.Attributes

No .NET Core, um UnauthorizedAccessException é gerado quando o chamador tenta definir um valor de atributo de arquivo, mas sem permissão de gravação.

Descrição das alterações

No .NET Framework, um ArgumentException é gerado quando o chamador tenta definir um valor de atributo de arquivo em FileSystemInfo.Attributes, mas sem permissão de gravação. Já no .NET Core, um UnauthorizedAccessException é gerado. (No .NET Core, um ArgumentException ainda será gerado se o chamador tentar definir um atributo de arquivo inválido).

Versão introduzida

1,0

Modifique as instruções catch para capturar um UnauthorizedAccessException, em vez de ArgumentException ou além dele, conforme o necessário.

Categoria

Bibliotecas principais do .NET

APIs afetadas


Não há suporte para o tratamento de exceções de estado corrompido

Não há suporte para o tratamento de exceções de estado de processo corrompido no .NET Core.

Descrição das alterações

Anteriormente, as exceções de estado de processo corrompido podiam ser capturadas e tratadas por manipuladores de exceção de código gerenciado, por exemplo, usando uma instrução try-catch em C#.

Do .NET Core 1.0 em diante, as exceções de estado de processo corrompido não podem ser tratadas pelo código gerenciado. O Common Language Runtime não fornece exceções de estado de processo corrompido para código gerenciado.

Versão introduzida

1,0

Evite a necessidade de lidar com exceções de estado de processo corrompido resolvendo as situações que as causam. Se for absolutamente necessário lidar com exceções de estado de processo corrompido, escreva o manipulador de exceção em código C ou C++.

Categoria

Bibliotecas principais do .NET

APIs afetadas


As propriedades do UriBuilder não acrescentam mais caracteres à esquerda

UriBuilder.Fragment não acrescenta mais um caractere # à esquerda e UriBuilder.Query não acrescenta mais um caractere ? à esquerda quando já existe um.

Descrição das alterações

No .NET Framework, as propriedades UriBuilder.Fragment e UriBuilder.Query sempre acrescentam um caractere # ou ?, respectivamente, ao valor que está sendo armazenado. Esse comportamento pode resultar em vários caracteres # ou ? no valor armazenado quando a cadeia de caracteres já contém um desses caracteres à esquerda. Por exemplo, o valor de UriBuilder.Fragment pode se tornar ##main.

Do .NET Core 1.0 em diante, essas propriedades não acrescentam mais os caracteres # ou ? ao valor armazenado quando já existe um no início da cadeia de caracteres.

Versão introduzida

1,0

Você não precisa mais remover explicitamente nenhum desses caracteres à esquerda ao definir os valores da propriedade. Isso é muito útil ao acrescentar valores, porque você não precisa mais remover o # ou ? à esquerda a cada acréscimo.

Por exemplo, o snippet de código a seguir mostra a diferença de comportamento entre o .NET Framework e .NET Core.

var builder = new UriBuilder();
builder.Query = "one=1";
builder.Query += "&two=2";
builder.Query += "&three=3";
builder.Query += "&four=4";

Console.WriteLine(builder.Query);
  • No .NET Framework, a saída é ????one=1&two=2&three=3&four=4.
  • No .NET Core, a saída é ?one=1&two=2&three=3&four=4.

Categoria

Bibliotecas principais do .NET

APIs afetadas


Process.StartInfo gera uma InvalidOperationException para processos que você não iniciou

A leitura da propriedade Process.StartInfo em processos que o código não iniciou gera uma InvalidOperationException.

Descrição das alterações

No .NET Framework, o acesso à propriedade Process.StartInfo em processos que o código não iniciou retorna um objeto fictício ProcessStartInfo. O objeto fictício contém valores padrão para todas as propriedades, exceto EnvironmentVariables.

Do .NET Core 1.0 em diante, se você ler a propriedade Process.StartInfo de um processo que não iniciou (ou seja, chamando Process.Start), será gerada uma InvalidOperationException.

Versão introduzida

1,0

Não acesse a propriedade Process.StartInfo em processos que o código não iniciou. Por exemplo, não leia essa propriedade para processos retornados por Process.GetProcesses.

Categoria

Bibliotecas principais do .NET

APIs afetadas