Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Este artigo é uma especificação de recurso. A especificação serve como o documento de design para o recurso. Ela inclui alterações de especificação propostas, juntamente com as informações necessárias durante o design e o desenvolvimento do recurso. Esses artigos são publicados até que as alterações de especificação propostas sejam finalizadas e incorporadas na especificação ECMA atual.
Pode haver algumas divergências entre a especificação do recurso e a implementação concluída. Essas diferenças são capturadas nas notas pertinentes da reunião de design de idioma (LDM).
Você pode saber mais sobre o processo de adoção de speclets de recursos no padrão de linguagem C# no artigo sobre as especificações de .
Problema do especialista: https://github.com/dotnet/csharplang/issues/114
Resumo
A linguagem adicionará dois novos recursos ao redor da instrução using
para tornar o gerenciamento de recursos mais simples: using
deve reconhecer um padrão descartável além de IDisposable
e adicionar uma instrução using
à linguagem.
Motivação
A instrução using
é uma ferramenta eficaz para o gerenciamento de recursos hoje, mas requer uma quantidade considerável de formalidade. Métodos que têm vários recursos para gerenciar podem ficar sobrecarregados sintaticamente com uma série de instruções using
. Essa carga de sintaxe é suficiente para que a maioria das diretrizes de estilo de codificação tenha explicitamente uma exceção entre colchetes para esse cenário.
A declaração using
remove grande parte da cerimônia aqui e coloca o C# no mesmo nível de outras linguagens que incluem blocos de gerenciamento de recursos. Além disso, o using
baseado em padrão permite que os desenvolvedores expandam o conjunto de tipos que podem participar aqui. Em muitos casos, eliminando a necessidade de criar tipos encapsuladores que existem apenas para possibilitar o uso de valores em uma instrução using
.
Juntos, esses recursos permitem que os desenvolvedores simplifiquem e expandam os cenários em que using
podem ser aplicados.
Projeto detalhado
usando declaração
A linguagem permitirá que using
seja adicionado a uma declaração de variável local. Essa declaração terá o mesmo efeito que declarar a variável em uma instrução using
no mesmo local.
if (...)
{
using FileStream f = new FileStream(@"C:\source\using.md");
// statements
}
// Equivalent to
if (...)
{
using (FileStream f = new FileStream(@"C:\source\using.md"))
{
// statements
}
}
O tempo de vida de um using
local se estenderá até o final do escopo no qual ele é declarado. Os using
locais serão descartados na ordem inversa em que foram declarados.
{
using var f1 = new FileStream("...");
using var f2 = new FileStream("...");
using var f3 = new FileStream("...");
...
// Dispose f3
// Dispose f2
// Dispose f1
}
Não há restrições relacionadas ao goto
ou a qualquer outra construção de fluxo de controle em relação a uma declaração de using
. Em vez disso, o código age exatamente como faria para a declaração using
equivalente:
{
using var f1 = new FileStream("...");
target:
using var f2 = new FileStream("...");
if (someCondition)
{
// Causes f2 to be disposed but has no effect on f1
goto target;
}
}
Um local declarado em uma declaração local using
será implicitamente somente de leitura. Isso corresponde ao comportamento das variáveis locais declaradas em uma instrução using
.
A gramática da linguagem para declarações de using
será a seguinte:
local-using-declaration:
'using' type using-declarators
using-declarators:
using-declarator
using-declarators , using-declarator
using-declarator:
identifier = expression
Restrições em torno da declaração de using
:
- Não pode aparecer diretamente dentro de um rótulo
case
, mas deve estar dentro de um bloco dentro do rótulocase
. - Pode não aparecer como parte de uma declaração de variável
out
. - Deve ter um inicializador para cada declarador.
- O tipo local deve ser implicitamente conversível para
IDisposable
ou atender ao padrãousing
.
uso baseado em padrões
A linguagem adicionará a noção de um padrão descartável para tipos de ref struct
: esse é um ref struct
que tem um método de instância de Dispose
acessível. Os tipos que se ajustam ao padrão descartável podem participar de uma instrução ou declaração using
sem a necessidade de implementar IDisposable
.
ref struct Resource
{
public void Dispose() { ... }
}
using (var r = new Resource())
{
// statements
}
Isso permitirá que os desenvolvedores utilizem using
para tipos ref struct
. Esses tipos não podem implementar interfaces no C# 8 e, portanto, não podem participar nas instruções using
.
As mesmas restrições de uma declaração using
tradicional se aplicam aqui também: variáveis locais declaradas em using
são somente leitura, um valor null
não causará uma exceção etc. A geração de código será diferente apenas porque não haverá uma conversão para IDisposable
antes de chamar Dispose:
{
Resource r = new Resource();
try {
// statements
}
finally {
if (r != null) r.Dispose();
}
}
Para se adequar ao padrão descartável, o método Dispose
deve ser um membro de instância acessível, sem parâmetros e ter um tipo de retorno void
. Não pode ser um método de extensão.
Considerações
Nenhuma dessas considerações foi implementada em C# 8
rótulos de casos sem blocos
Um using declaration
é ilegal diretamente dentro de um rótulo de case
devido a complicações em torno de seu tempo de vida real. Uma possível solução é simplesmente oferecer a ele o mesmo tempo de vida de um out var
no mesmo local. Foi considerado que a complexidade adicional para a implementação do recurso e a facilidade da solução alternativa (basta adicionar um bloco ao rótulo case
) não justificam seguir por esse caminho.
Expansões futuras
locais fixos
Uma instrução fixed
possui todas as propriedades das instruções using
que motivaram a possibilidade de ter using
locais. Deve-se considerar a extensão desse recurso também para locais fixed
. As regras de tempo de vida e ordenação devem se aplicar igualmente para using
e fixed
aqui.
C# feature specifications