Eu li que o .NET suporta retorno de referências, mas o C # não. Existe um motivo especial? Por que não posso fazer algo como:
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
c#
.net
reference
return-type
Tom Sarduy
fonte
fonte
return ref x
C# 7
:)Respostas:
Esta questão foi o assunto do meu blog em 23 de junho de 2011 . Obrigado pela ótima pergunta!
A equipe do C # está considerando isso para o C # 7. Consulte https://github.com/dotnet/roslyn/issues/5233 para obter detalhes.
UPDATE: O recurso chegou ao C # 7!
Você está certo; O .NET oferece suporte a métodos que retornam referências gerenciadas para variáveis. O .NET também suporta variáveis locais que contêm referências gerenciadas para outras variáveis. (Observe, no entanto, que o .NET não oferece suporte a campos ou matrizes que contêm referências gerenciadas para outras variáveis, pois isso complica demais a história da coleta de lixo. Além disso, os tipos de "referência gerenciada à variável" não são conversíveis em objeto e, portanto, não podem ser usados como argumentos de tipo para tipos ou métodos genéricos.)
O comentarista "RPM1984", por algum motivo, pediu uma citação para esse fato. RPM1984 Convido você a ler a Partição I da Seção 8.2.1.1 da especificação CLI, "Ponteiros gerenciados e tipos relacionados" para obter informações sobre esse recurso do .NET.
É totalmente possível criar uma versão do C # que ofereça suporte a esses dois recursos. Você poderia então fazer coisas como
e depois chame-o com
Eu sei empiricamente que é possível criar uma versão do C # que ofereça suporte a esses recursos, porque eu o fiz . Programadores avançados, particularmente pessoas portadoras de código C ++ não gerenciado, geralmente nos pedem mais capacidade semelhante a C ++ para fazer coisas com referências sem precisar sair do grande martelo de usar ponteiros e fixar memória em todo o lugar. Ao usar referências gerenciadas, você obtém esses benefícios sem pagar o custo de estragar o desempenho da coleta de lixo.
Consideramos esse recurso e, na verdade, implementamos o suficiente para mostrar a outras equipes internas para obter feedback. No entanto, no momento, com base em nossa pesquisa , acreditamos que o recurso não possui apelo suficientemente amplo ou casos de uso convincentes para transformá-lo em um recurso real de idioma suportado . Temos outras prioridades mais altas e uma quantidade limitada de tempo e esforço disponível; portanto, não faremos esse recurso tão cedo.
Além disso, fazê-lo corretamente exigiria algumas alterações no CLR. No momento, o CLR trata os métodos de retorno de retorno como legais, mas não verificáveis, porque não temos um detector que detecte essa situação:
M3 retorna o conteúdo da variável local do M2, mas o tempo de vida dessa variável terminou! É possível escrever um detector que determine o uso de retornos ref que claramente não violam a segurança da pilha. O que faríamos é escrever um detector desse tipo e, se o detector não pudesse provar a segurança da pilha, não permitiríamos o uso de retornos de ref nessa parte do programa. Não é uma quantidade enorme de trabalho para desenvolvedores fazer isso, mas é muito oneroso para as equipes de teste garantir que realmente tenhamos todos os casos. É apenas outra coisa que aumenta o custo do recurso a um ponto em que, no momento, os benefícios não superam os custos.
Se você pode descrever para mim por que você deseja esse recurso, eu realmente aprecio isso . Quanto mais informações tivermos de clientes reais sobre o motivo pelo qual eles desejam, maior a probabilidade de ele entrar no produto algum dia. É um recurso bonitinho e eu gostaria de poder levá-lo aos clientes de alguma forma, se houver interesse suficiente.
(Consulte também perguntas relacionadas É possível retornar uma referência a uma variável em C #? E posso usar uma referência dentro de uma função C # como C ++? )
fonte
y
vivo depois de voltarM2
? Eu esperaria que esse recurso funcionasse como lambdas capturando locais. Ou é o comportamento que você propôs porque é como o CLR lida com esse cenário?Você está falando de métodos que retornam uma referência a um tipo de valor. O único exemplo interno em C # que eu conheço é o acessador de matriz de um tipo de valor:
e agora crie uma matriz dessa estrutura:
Nesse caso
points[0]
, o indexador de matriz está retornando uma referência para struct. É impossível escrever seu próprio indexador (por exemplo, para uma coleção personalizada), que tenha o mesmo comportamento "retornar uma referência".Eu não projetei a linguagem C #, então não conheço todo o raciocínio por trás de não suportá-la, mas acho que a resposta curta pode ser: podemos nos dar bem sem ela.
fonte
Você sempre pode fazer algo como:
fonte
O C # 7.0 tem suporte para retornar referências. Veja minha resposta aqui .
fonte