Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo descreve novos recursos nas bibliotecas .NET para .NET 10. É atualizado para o Preview 5.
Criptografia
- Localizar certificados por impressões digitais diferentes de SHA-1
- Encontre dados codificados em PEM em ASCII/UTF-8
- Algoritmo de encriptação para exportação PKCS#12/PFX
- Criptografia pós-quântica (PQC)
Localizar certificados por impressões digitais diferentes de SHA-1
Encontrar certificados exclusivamente por impressão digital é uma operação bastante comum, mas o X509Certificate2Collection.Find(X509FindType, Object, Boolean) método (para o FindByThumbprint modo) procura apenas o valor de impressão digital SHA-1.
Há algum risco em usar o Find
método para encontrar impressões digitais SHA-2-256 ("SHA256") e SHA-3-256, uma vez que esses algoritmos de hash têm os mesmos comprimentos.
Em vez disso, o .NET 10 introduz um novo método que aceita o nome do algoritmo de hash a ser usado para correspondência.
X509Certificate2Collection coll = store.Certificates.FindByThumbprint(HashAlgorithmName.SHA256, thumbprint);
Debug.Assert(coll.Count < 2, "Collection has too many matches, has SHA-2 been broken?");
return coll.SingleOrDefault();
Encontre dados codificados em PEM em ASCII/UTF-8
A codificação PEM (originalmente Privacy Enhanced Mail, mas agora amplamente usada fora do e-mail) é definida para "texto", o que significa que a classe foi projetada para ser executada PemEncoding em String e ReadOnlySpan<char>
. No entanto, é comum (especialmente no Linux) ter algo como um certificado escrito em um arquivo que usa a codificação ASCII (string). Historicamente, isso significava que você precisava abrir o arquivo e converter os bytes em caracteres (ou uma cadeia de caracteres) antes de poder usar PemEncoding
o .
O novo PemEncoding.FindUtf8(ReadOnlySpan<Byte>) método aproveita o fato de que o PEM é definido apenas para caracteres ASCII de 7 bits e que o ASCII de 7 bits tem uma sobreposição perfeita com valores UTF-8 de byte único. Ao chamar esse novo método, você pode pular a conversão UTF-8/ASCII-to-char e ler o arquivo diretamente.
byte[] fileContents = File.ReadAllBytes(path);
-char[] text = Encoding.ASCII.GetString(fileContents);
-PemFields pemFields = PemEncoding.Find(text);
+PemFields pemFields = PemEncoding.FindUtf8(fileContents);
-byte[] contents = Base64.DecodeFromChars(text.AsSpan()[pemFields.Base64Data]);
+byte[] contents = Base64.DecodeFromUtf8(fileContents.AsSpan()[pemFields.Base64Data]);
Algoritmo de encriptação para exportação PKCS#12/PFX
Os novos métodos em ExportPkcs12 permitem que os chamadores escolham quais algoritmos de criptografia e digests são utilizados para gerar o resultado:
- Pkcs12ExportPbeParameters.Pkcs12TripleDesSha1 indica o padrão de facto da era Windows XP. Ele produz uma saída suportada por quase todas as bibliotecas e plataformas que suportam a leitura de PKCS#12/PFX escolhendo um algoritmo de criptografia mais antigo.
- Pkcs12ExportPbeParameters.Pbes2Aes256Sha256 indica que AES deve ser usado em vez de 3DES (e SHA-2-256 em vez de SHA-1), mas a saída pode não ser compreendida por todos os leitores (como o Windows XP).
Se quiseres ainda mais controlo, podes usar a sobrecarga que aceita um PbeParameters.
Criptografia pós-quântica (PQC)
O .NET 10 inclui suporte para três novos algoritmos assimétricos: ML-KEM (FIPS 203), ML-DSA (FIPS 204) e SLH-DSA (FIPS 205). Os novos tipos são:
-
System.Security.Cryptography.MLKem
-
System.Security.Cryptography.MLDsa
-
System.Security.Cryptography.SlhDsa
Como acrescenta pouco benefício, esses novos tipos não derivam de AsymmetricAlgorithm. Em vez da AsymmetricAlgorithm
abordagem de criar um objeto e, em seguida, importar uma chave para ele, ou gerar uma nova chave, todos os novos tipos usam métodos estáticos para gerar ou importar uma chave:
using System;
using System.IO;
using System.Security.Cryptography;
private static bool ValidateMLDsaSignature(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, string publicKeyPath)
{
string publicKeyPem = File.ReadAllText(publicKeyPath);
using (MLDsa key = MLDsa.ImportFromPem(publicKeyPem))
{
return key.VerifyData(data, signature);
}
}
E em vez de definir propriedades de objeto e uma chave materializar-se, a geração de chaves nesses novos tipos incorpora todas as opções necessárias.
using (MLKem key = MLKem.GenerateKey(MLKemAlgorithm.MLKem768))
{
string publicKeyPem = key.ExportSubjectPublicKeyInfoPem();
...
}
Todos esses algoritmos continuam com o padrão de ter uma propriedade estática IsSupported
para indicar se o algoritmo é suportado no sistema atual.
Atualmente, os algoritmos PQC só estão disponíveis em sistemas onde as bibliotecas criptográficas do sistema são OpenSSL 3.5 (ou mais recentes). O suporte ao Windows CNG será adicionado em breve. Além disso, as novas classes são todas marcadas como [Experimental]
no diagnóstico SYSLIB5006
até que o desenvolvimento seja concluído.
Globalização e data/hora
- Novos sobrecarregamentos de métodos no ISOWeek para o tipo DateOnly
- Ordenação numérica para comparação de cadeias de caracteres
-
Nova
TimeSpan.FromMilliseconds
sobrecarga com parâmetro único
Novas sobrecargas de métodos em ISOWeek para o tipo DateOnly
A ISOWeek classe foi originalmente projetada para trabalhar exclusivamente com DateTime, pois foi introduzida antes do DateOnly tipo existir. Agora que DateOnly
está disponível, faz sentido que ISOWeek
também o suporte. As seguintes sobrecargas são novas:
Ordenação numérica para comparação de cadeias de caracteres
A comparação numérica de cadeias é um recurso altamente solicitado para comparar cadeias numericamente em vez de lexicograficamente. Por exemplo, 2
é menor que 10
, por isso "2"
deve aparecer antes "10"
quando ordenado numericamente. Da mesma forma, "2"
e "02"
são iguais numericamente. Com a nova NumericOrdering opção, agora é possível fazer esses tipos de comparações:
StringComparer numericStringComparer = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.NumericOrdering);
Console.WriteLine(numericStringComparer.Equals("02", "2"));
// Output: True
foreach (string os in new[] { "Windows 8", "Windows 10", "Windows 11" }.Order(numericStringComparer))
{
Console.WriteLine(os);
}
// Output:
// Windows 8
// Windows 10
// Windows 11
HashSet<string> set = new HashSet<string>(numericStringComparer) { "007" };
Console.WriteLine(set.Contains("7"));
// Output: True
Esta opção não é válida para as seguintes operações de cadeia de caracteres baseadas em índice: IndexOf
, LastIndexOf
, StartsWith
, EndsWith
IsPrefix
, e IsSuffix
.
Nova TimeSpan.FromMilliseconds
sobrecarga com parâmetro único
O TimeSpan.FromMilliseconds(Int64, Int64) método foi introduzido anteriormente sem adicionar uma sobrecarga que leva um único parâmetro.
Embora isso funcione como o segundo parâmetro é opcional, ele causa um erro de compilação quando usado em uma expressão LINQ como:
Expression<Action> a = () => TimeSpan.FromMilliseconds(1000);
O problema surge porque as expressões LINQ não podem lidar com parâmetros opcionais. Para resolver isso, o .NET 10 introduz uma nova sobrecarga que usa um único parâmetro. Altera igualmente o método existente para tornar obrigatório o segundo parâmetro.
Cordas
APIs de normalização de strings para trabalhar com intervalo de caracteres
A normalização de cadeia de caracteres Unicode tem sido suportada há muito tempo, mas as APIs existentes só funcionavam com o tipo de cadeia de caracteres. Isso significa que os chamadores com dados armazenados em diferentes formas, como matrizes de caracteres ou vãos, devem alocar uma nova cadeia de caracteres para usar essas APIs. Além disso, as APIs que retornam uma cadeia de caracteres normalizada sempre alocam uma nova cadeia de caracteres para representar a saída normalizada.
O .NET 10 apresenta novas APIs que funcionam com extensões de caracteres, que expandem a normalização além dos tipos de cadeia de caracteres e ajudam a evitar alocações desnecessárias:
- StringNormalizationExtensions.GetNormalizedLength(ReadOnlySpan<Char>, NormalizationForm)
- StringNormalizationExtensions.IsNormalized(ReadOnlySpan<Char>, NormalizationForm)
- StringNormalizationExtensions.TryNormalize(ReadOnlySpan<Char>, Span<Char>, Int32, NormalizationForm)
Coleções
Adicionais TryAdd
e TryGetValue
sobrecargas para OrderedDictionary<TKey, TValue>
OrderedDictionary<TKey,TValue> fornece TryAdd
e TryGetValue
para adição e recuperação como qualquer outra IDictionary<TKey, TValue>
implementação. No entanto, há cenários em que você pode querer executar mais operações, portanto, novas sobrecargas são adicionadas que retornam um índice para a entrada:
Este índice pode então ser usado com GetAt e SetAt para acesso rápido à entrada. Um exemplo de aplicação da nova sobrecarga TryAdd
é o de adicionar ou atualizar um par chave-valor no dicionário ordenado.
// Try to add a new key with value 1.
if (!orderedDictionary.TryAdd(key, 1, out int index))
{
// Key was present, so increment the existing value instead.
int value = orderedDictionary.GetAt(index).Value;
orderedDictionary.SetAt(index, value + 1);
}
Esta nova API já é usada em JsonObject e melhora o desempenho da atualização de propriedades em 10 a 20%.
Serialização
Permitir a especificação de ReferenceHandler em JsonSourceGenerationOptions
Quando você usa geradores de código-fonte para serialização JSON, o contexto gerado é gerado quando os ciclos são serializados ou desserializados. Agora você pode personalizar esse comportamento especificando o ReferenceHandler no JsonSourceGenerationOptionsAttribute. Aqui está um exemplo usando JsonKnownReferenceHandler.Preserve
:
public static void MakeSelfRef()
{
SelfReference selfRef = new SelfReference();
selfRef.Me = selfRef;
Console.WriteLine(JsonSerializer.Serialize(selfRef, ContextWithPreserveReference.Default.SelfReference));
// Output: {"$id":"1","Me":{"$ref":"1"}}
}
[JsonSourceGenerationOptions(ReferenceHandler = JsonKnownReferenceHandler.Preserve)]
[JsonSerializable(typeof(SelfReference))]
internal partial class ContextWithPreserveReference : JsonSerializerContext
{
}
internal class SelfReference
{
public SelfReference Me { get; set; } = null!;
}
System.Numerics
Mais métodos de transformação de matriz de esquerda
O .NET 10 adiciona as APIs restantes para criar matrizes de transformação canhotas para matrizes de billboard e constrained-billboard. Você pode usar esses métodos como seus homólogos destros existentes, por exemplo, CreateBillboard(Vector3, Vector3, Vector3, Vector3)ao usar um sistema de coordenadas canhoto:
- Matrix4x4.CreateBillboardLeftHanded(Vector3, Vector3, Vector3, Vector3)
- Matrix4x4.CreateConstrainedBillboardLeftHanded(Vector3, Vector3, Vector3, Vector3, Vector3)
Melhoramentos de tensores
A interface System.Numerics.Tensors agora inclui uma versão não genérica, IReadOnlyTensor, para operações como o acesso a Lengths e Strides. As operações de fatia não copiam mais dados, o que melhora o desempenho. Além disso, pode aceder a dados de forma não genérica, encaixotando para object
quando o desempenho não é crítico.
Validação de opções
Novo construtor AOT-safe para ValidationContext
A ValidationContext classe, usada durante a validação de opções, inclui uma nova sobrecarga de construtor que aceita explicitamente o displayName
parâmetro:
ValidationContext(Object, String, IServiceProvider, IDictionary<Object,Object>)
O nome de exibição garante a segurança da AOT e permite seu uso em compilações nativas sem avisos.
Diagnóstico
-
Suporte para URLs de esquema de telemetria em
ActivitySource
eMeter
- Suporte de rastreamento fora do processo para eventos e links de atividade
- Suporte para limitação de taxa e amostragem de rastreamento
Suporte para URLs de esquema de telemetria em ActivitySource
e Meter
ActivitySource e Meter agora suporta a especificação de uma URL de esquema de telemetria durante a construção, que se alinha com as especificações do OpenTelemetry . O esquema de telemetria garante consistência e compatibilidade para dados de rastreamento e métricas. Além disso, o .NET 10 apresenta ActivitySourceOptions, que simplifica a criação de instâncias com várias opções de configuração (incluindo a URL do esquema de ActivitySource).
As novas APIs são:
- ActivitySource(ActivitySourceOptions)
- ActivitySource.TelemetrySchemaUrl
- Meter.TelemetrySchemaUrl
- ActivitySourceOptions
Suporte de rastreamento fora de processo para eventos de atividade e links
A Activity classe permite o rastreamento distribuído rastreando o fluxo de operações entre serviços ou componentes. O .NET suporta a serialização desses dados de rastreamento fora do processo através do fornecedor de origem de eventos Microsoft-Diagnostics-DiagnosticSource
. Um Activity
pode incluir metadados adicionais, como ActivityLink e ActivityEvent. O .NET 10 adiciona suporte para serializar esses links e eventos, de modo que os dados de rastreamento fora de processo agora incluem essas informações. Por exemplo:
Events->"[(TestEvent1,2025-03-27T23:34:10.6225721+00:00,[E11:EV1,E12:EV2]),(TestEvent2,2025-03-27T23:34:11.6276895+00:00,[E21:EV21,E22:EV22])]"
Links->"[(19b6e8ea216cb2ba36dd5d957e126d9f,98f7abcb3418f217,Recorded,null,false,[alk1:alv1,alk2:alv2]),(2d409549aadfdbdf5d1892584a5f2ab2,4f3526086a350f50,None,null,false)]"
Suporte para amostragem de monitorização com limite de taxa
Quando os dados de rastreamento distribuídos são serializados fora de processo por meio do provedor de origem de eventos Microsoft-Diagnostics-DiagnosticSource
, todas as atividades registradas podem ser emitidas ou a amostragem pode ser aplicada com base em uma proporção de rastreamento.
Uma nova opção de amostragem chamada Amostragem de Limitação de Taxa restringe o número de atividades raiz serializadas por segundo. Isso ajuda a controlar o volume de dados com mais precisão.
Os agregadores de dados de rastreamento fora do processo podem habilitar e configurar esta amostragem especificando a opção em FilterAndPayloadSpecs
. Por exemplo, a configuração a seguir limita a serialização a 100 atividades raiz por segundo em todas as ActivitySource
instâncias:
[AS]*/-ParentRateLimitingSampler(100)
Arquivos ZIP
- Melhorias de desempenho e memória do ZipArchive
- Novas APIs ZIP assíncronas
- Melhoria de desempenho no GZipStream para fluxos concatenados
Melhorias de desempenho e memória do ZipArchive
O .NET 10 melhora o desempenho e o uso de memória do ZipArchive.
Primeiro, a forma como as entradas são gravadas no ZipArchive
quando está em modo Update
foi otimizada. Anteriormente, todas as ZipArchiveEntry instâncias eram carregadas na memória e reescritas, o que poderia levar a altos gargalos de uso de memória e desempenho. A otimização reduz o uso de memória e melhora o desempenho, evitando a necessidade de carregar todas as entradas na memória.
Em segundo lugar, a extração de entradas agora é paralelizada e as estruturas de dados internas são otimizadas para um melhor uso da ZipArchive memória. Essas melhorias abordam problemas relacionados a gargalos de desempenho e alto uso de memória, tornando ZipArchive
mais eficiente e rápido, especialmente ao lidar com arquivos grandes.
Novas APIs ZIP assíncronas
O .NET 10 introduz novas APIs assíncronas que facilitam a execução de operações sem bloqueio ao ler ou gravar em arquivos ZIP. Este recurso foi muito solicitado pela comunidade.
Novos async
métodos estão disponíveis para extrair, criar e atualizar arquivos ZIP. Esses métodos permitem que os desenvolvedores lidem com arquivos grandes de forma eficiente e melhorem a capacidade de resposta do aplicativo, especialmente em cenários que envolvem operações vinculadas a E/S. Esses métodos incluem:
- ZipArchive.CreateAsync(Stream, ZipArchiveMode, Boolean, Encoding, CancellationToken)
- ZipArchiveEntry.OpenAsync(CancellationToken)
- ZipFile.CreateFromDirectoryAsync
- ZipFile.ExtractToDirectoryAsync
- ZipFile.OpenAsync
- ZipFile.OpenReadAsync(String, CancellationToken)
- ZipFileExtensions.CreateEntryFromFileAsync
- ZipFileExtensions.ExtractToDirectoryAsync
- ZipFileExtensions.ExtractToFileAsync
Para obter exemplos de como usar essas APIs, consulte a postagem do blog Preview 4.
Melhoria de desempenho no GZipStream para fluxos concatenados
Uma contribuição da comunidade melhorou o desempenho ao processar fluxos de GZipStream dados GZip concatenados. Anteriormente, cada novo segmento de fluxo descartava e realocava o interno ZLibStreamHandle
, o que resultava em alocações de memória adicionais e sobrecarga de inicialização. Com essa alteração, o identificador agora é redefinido e reutilizado para reduzir as alocações de memória gerenciada e não gerenciada e melhorar o tempo de execução. O maior impacto (~35% mais rápido) é visto ao processar um grande número de pequenos fluxos de dados. Esta alteração:
- Elimina a alocação repetida de ~64-80 bytes de memória por fluxo concatenado, com economia adicional de memória não gerenciada.
- Reduz o tempo de execução em aproximadamente 400 ns por fluxo concatenado.