O comportamento é extremamente semelhante ao Array.Resize
método no .NET. Para entender o que está acontecendo, pode ser útil examinar o histórico do .
token em C, C ++, Java, C # e Swift.
Em C, uma estrutura nada mais é do que uma agregação de variáveis. A aplicação de a .
uma variável do tipo de estrutura acessará uma variável armazenada dentro da estrutura. Ponteiros para objetos não contêm agregações de variáveis, mas as identificam . Se alguém tem um ponteiro que identifica uma estrutura, o->
operador poderá ser usado para acessar uma variável armazenada dentro da estrutura identificada pelo ponteiro.
No C ++, estruturas e classes não apenas agregam variáveis, mas também podem anexar código a elas. Usar .
para invocar um método em uma variável solicitará que esse método atue sobre o conteúdo da própria variável ; o uso ->
de uma variável que identifica um objeto solicitará que o método atue no objeto identificado pela variável.
Em Java, todos os tipos de variáveis personalizadas simplesmente identificam objetos e a invocação de um método em uma variável informa ao método qual objeto é identificado pela variável. As variáveis não podem conter nenhum tipo de tipo de dado composto diretamente, nem existe um meio pelo qual um método possa acessar uma variável na qual é chamado. Essas restrições, embora limitem semanticamente, simplificam bastante o tempo de execução e facilitam a validação de código de código; essas simplificações reduziram a sobrecarga de recursos do Java em um momento em que o mercado era sensível a esses problemas e, portanto, ajudaram a ganhar força no mercado. Eles também significavam que não havia necessidade de um token equivalente ao .
usado em C ou C ++. Embora o Java pudesse ter usado,->
da mesma maneira que C e C ++, os criadores optaram por usar caracteres únicos.
já que não era necessário para nenhum outro propósito.
Em C # e outras linguagens .NET, as variáveis podem identificar objetos ou reter tipos de dados compostos diretamente. Quando usado em uma variável de um tipo de dados composto, .
atua sobre o conteúdo da variável; quando usado em uma variável do tipo de referência, .
atua sobre o objeto identificadopor isso. Para alguns tipos de operações, a distinção semântica não é particularmente importante, mas para outros é. As situações mais problemáticas são aquelas em que o método de um tipo de dados composto que modifica a variável na qual é invocado é invocado em uma variável somente leitura. Se for feita uma tentativa de chamar um método em um valor ou variável somente leitura, os compiladores geralmente copiam a variável, deixam o método agir sobre isso e descartam a variável. Isso geralmente é seguro com métodos que apenas leem a variável, mas não é seguro com métodos que gravam nela. Infelizmente, .does ainda não possui meios de indicar quais métodos podem ser usados com segurança com essa substituição e quais não podem.
No Swift, os métodos agregados podem indicar expressamente se eles modificarão a variável sobre a qual são invocados, e o compilador proibirá o uso de métodos de mutação em variáveis somente leitura (em vez de fazer com que elas modifiquem cópias temporárias da variável que, em seguida, ser descartado). Devido a essa distinção, o uso do .
token para chamar métodos que modificam as variáveis nas quais são invocadas é muito mais seguro no Swift do que no .NET. Infelizmente, o fato de o mesmo .
token ser usado para esse fim e atuar sobre um objeto externo identificado por uma variável significa que a possibilidade de confusão permanece.
Se tivesse uma máquina do tempo e voltasse à criação de C # e / ou Swift, seria possível evitar retroativamente grande parte da confusão em torno desses problemas, fazendo com que os idiomas usassem os tokens .
e de ->
uma maneira muito mais próxima do uso do C ++. Métodos de agregados e tipos de referência podem ser usados .
para atuar sobre a variável sobre a qual foram invocados e ->
sobre um valor (para compósitos) ou a coisa identificada por ele (para tipos de referência). Nenhuma linguagem é projetada dessa maneira, no entanto.
Em C #, a prática normal de um método para modificar uma variável na qual é invocado é passar a variável como ref
parâmetro para um método. Assim, chamar Array.Resize(ref someArray, 23);
quando someArray
identifica uma matriz de 20 elementos fará com someArray
que identifique uma nova matriz de 23 elementos, sem afetar a matriz original. O uso de ref
deixa claro que o método deve modificar a variável sobre a qual é invocado. Em muitos casos, é vantajoso poder modificar variáveis sem precisar usar métodos estáticos; Endereços rápidos, ou seja, usando .
sintaxe. A desvantagem é que perde esclarecimentos sobre quais métodos agem sobre variáveis e quais métodos agem sobre valores.