Pergunta

Eu entendo ponteiros e a necessidade raro usá-los em código C #. A minha pergunta é: qual é o raciocínio por trás ter que explicitamente estado "inseguro" em um bloco de código. Além disso, por que a opção do compilador ser alterado para permitir que o código "inseguro"?

Bottom Line: O que nos CLR (ou especificações de linguagem) torna por isso não podemos apenas usar ponteiros sempre que queremos (muito parecido com C e C ++) sem ter que digitar "inseguro" e alterar a opção do compilador?

Para esclarecimento: Eu sei o que "inseguro" e "seguro" código é. É apenas uma questão de por que devemos fazer todo o trabalho extra (ok, nem tanto adicional) apenas para ser capaz de usar esses recursos.

Foi útil?

Solução

Há uma entrevista com C # Criador Anders Hejlsberg que toques sobre o assunto aqui . Basicamente, exatamente o que @ Marc Gravell disse: typesafety primeiro, insegurança por declaração explícita.

Assim, para responder à sua pergunta: nada nos impede CLR-lo; é um idioma da língua projetada para permitir que você trabalhe com luvas de segurança ao lidar com tipos. Se você quiser tirar as luvas, a escolha é sua, mas você tem que fazer a escolha ativa para tirar as luvas.

Editar:

Para esclarecimento: Eu sei o que "Inseguro" e "seguro" código é. É apenas uma questão de por que devemos fazer todo o trabalho extra (ok, nem tanto adicional) apenas para ser capaz de usar esses recursos.

Como mencionado na entrevista que eu ligado, foi uma decisão de projeto explícito. C # é essencialmente uma evolução de Java e em Java, você não tem ponteiros em tudo. Mas os designers queria permitir ponteiros; no entanto, porque C # normalmente seria trazer desenvolvedores Java, eles sentiram que seria melhor se o padrão comportamento ser semelhante ao Java, ou seja, sem ponteiros, permitindo ainda o uso de ponteiros por declaração explícita.

Assim, o "trabalho extra" é deliberado para forçá-lo a pensar sobre o que você está fazendo antes de fazê-lo. Por ser explícito, força-o a pelo menos considerar: "Por que estou fazendo isso Do I realmente precisa de um ponteiro quando um tipo de referência será suficiente"

Outras dicas

É em grande parte sobre ser verificável. Ao afirmar unsafe, as luvas estão fora - o sistema não pode mais garantia de que seu código não será executado amok. Na maioria dos casos, é altamente desejável para ficar na zona de segurança.

Isto torna-se mais perceptível com confiança parcial (suplementos etc), mas ainda é valioso no código regular.

Na verdade, o CLR não faz exigências em tudo sobre um interruptor / inseguro ou palavra-chave. Na verdade, C ++ / CLI (a linguagem C ++ que é executado sob a CLR) não tem interruptor de tal / inseguro, e ponteiros pode ser usado livremente no CLR.

Assim, gostaria de reformular a sua pergunta como "Por que C # requer o uso de / inseguro antes ponteiros podem ser usados?" E a resposta a essa pergunta é como afirmado em outras respostas dadas aqui: para ajudar o usuário tomar uma decisão consciente para perder a capacidade de executar em qualquer coisa menos do que o modo Full Trust na CLR. C ++ quase sempre requer confiança total na CLR e C # pode , sempre que você chamar o código que requer confiança total, ou sempre que você usar ponteiros.

Quando você usa um bloco inseguro, tem o efeito de fazer o unverifiable código. Isso requer determinadas permissões para executar e você pode não querer permitir que na sua saída (especialmente se você estiver em um ambiente de código compartilhado), para que haja um interruptor no compilador para não permitir isso.

Pense nisso a partir do ponto de vista oposto: porque não é marcado como não seguro, você pode inferir que a maior parte do código é "seguro" por padrão. Então, o que significa ser "seguro"? Para código .Net, este inclui (mas não pode ser limitada a):

  • O coletor de lixo pode fazer negócios como de costume.
  • As referências a um tipo específico irá se referir a objetos desse tipo (ou nulo).
  • Código é garantido para cumprir com os requisitos de confiança / segurança do .NET.
  • O código é matematicamente não comprovada a memória diretamente toque fora seu próprio AppDomain. Pode parecer trivial, mas imagine se você tiver vários AppDomains no mesmo aplicativo. O programador pode confiantemente tratá-los como logicamente separado.

Toda vez que você usar ponteiros você tem a chance de quebrar qualquer uma dessas garantias. Portanto marcação código como inseguros desiste essas proteções.

Em suma, .NET quer que você afirmar a sua intenção.

Claro, o compilador pode inferir a necessidade da bandeira "inseguro". Mas os designers quer que seja uma decisão deliberada.

Para mim, é semelhante a uma série de requisitos sintáticos em C #:

  • nenhum caso interruptor sem pausa
  • no-nível de acesso "seções" (como o "público:" marcador em C ++)
  • há campos de classe usando o "var"

O padrão é que você não deve se mover ou coisa mudança um e inadvertidamente afetar o outro. Dentro da razão, eles querem mantê-lo de "tiro no próprio pé."

Muitos dos grandes, respostas informativas aqui -. Talvez isto vai mais à sua pergunta

Assim que é imediatamente óbvio que o código não será executado em serviços web sem permissões elevadas, etc.

Cultivando hábitos bons e segurança. Sempre que você usa um bloco inseguro em uma montagem, uma permissão NativeCode será exigida a partir da pilha. Isso pode, naturalmente, ser feito de forma implícita, mas não poderia também apenas remover a palavra-chave privada completamente? Eu acho que é bom para os desenvolvedores de força para exigir especificamente código inseguro antes que eles possam usá-lo.

A diferença mais significativa entre o código seguros e inseguros é que o código inseguro é inacessível pelo coletor de lixo do .net. Automatic GC é uma grande parte do vernáculo do .net e, quando você vai além de suas fronteiras, você muda muito do que pode ser assumida sobre o seu código.

Ponteiros em particular, permitem a criação de objetos na pilha sem referências GC. Isto leva a uma outra excelente razão para exigir código a ser marcado como "inseguro". Isso torna mais fácil para diminuir, onde um vazamento de memória é que vem quando você percebe que você tem um.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top