Pergunta

O código a seguir gera um erro de tempo de compilação como

Não é possível converter tipo 'string' para 'int'

string name = Session["name1"].ToString();
int i = (int)name;

Considerando que o código abaixo compila e executa com êxito:

string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);

Eu gostaria de saber:

  1. Por que o primeiro código gerar um erro em tempo de compilação?

  2. Qual é a diferença entre os trechos de código 2?

Foi útil?

Solução

(int)foo é simplesmente um elenco à Int32 (int em C #) tipo. Este é construído na CLR e requer que foo ser uma variável numérica (por exemplo float, long, etc.) Neste sentido, é muito semelhante a um molde em C.

Convert.ToInt32 é projetado para ser uma função de conversão geral. Ele faz um bom negócio mais de fundição; ou seja, ele pode converter de qualquer tipo primitivo a um int (mais notavelmente, a análise de um string). Você pode ver a lista completa de sobrecargas para este método aqui no MSDN .

E, como Stefan Steiger menciona em um comentário :

Além disso, nota que em um nível numérico, (int) foo trunca foo (ifoo = Math.Floor(foo)), enquanto usos Convert.ToInt32(foo) metade até mesmo arredondamento (rodadas x.5 para o mais próximo inteiro par, o que significa ifoo = Math.Round(foo)). O resultado é, assim, não apenas a implementação-sábio, mas também numericamente não o mesmo.

Outras dicas

(esta linha se refere a uma pergunta que foi incorporada) Você nunca deve usar (int)someString -. Que nunca vai funcionar (e o compilador não vai deixar você)

No entanto, int int.Parse(string) e bool int.TryParse(string, out int) (e suas várias sobrecargas) são jogo justo.

Pessoalmente, eu principalmente use apenas Convert quando estou lidando com reflexão, então para mim a escolha é Parse e TryParse. A primeira é quando eu esperar o valor de ser um número inteiro válido, e quer que ele lançar uma exceção contrário. A segunda é quando eu quero verificação se for um número inteiro válido -. Posso, então, decidir o que fazer quando é / não é

Para citar este Eric Lippert artigo :

o lançarei duas coisas contraditórias: "Verifique para ver se este objeto realmente é deste tipo, jogue se não é" e "esse objeto não é do tipo de dado, encontrar-me um valor equivalente, que pertence ao tipo dada ".

Então, o que você estava tentando fazer em 1.) é afirmar que sim uma String é um int. Mas essa afirmação falhar uma vez cadeia não é um int.

A razão 2.) sucede é porque Convert.ToInt32 () analisa a cadeia e retorna um int. Ele ainda pode falhar, por exemplo:

Convert.ToInt32("Hello");

resultado seria em uma exceção Argument.

Para resumir, a conversão de uma string para um Int é uma preocupação quadro, não é algo implícito no sistema de tipo .NET.

Uma cadeia não pode ser convertido para um int através de conversão explícita. Deve ser convertidos usando int.Parse.

Convert.ToInt32 basicamente envolve este método:

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}

Você está falando de uma operação C # fundição vs utilitários .NET conversão

  • C # linguagem de nível fundição usos parêntesis - por exemplo, (Int) - e suporte para conversão é limitada, baseando-se na compatibilidade implícito entre os tipos, ou instruções explicitamente definidos pelo programador por operadores de conversão .
  • Existem muitos métodos de conversão no .NET Framework, por exemplo, System.Convert , para permitir conversão entre tipos de dados iguais ou diferentes.

(Casting) sintaxe funciona em tipos de dados numéricos, e também sobre os tipos de dados "compatível". meios compatíveis com tipos de dados para os quais existe uma relação estabelecida através de herança (base ou seja / derivado classes) ou através da aplicação (isto é, as interfaces).

Fundição também pode trabalho entre os tipos de dados diferentes que têm operadores de conversão definido.

O System.Convert classe, por outro lado é um dos muitos mecanismos disponíveis para converter as coisas no sentido geral; ela contém lógica para converter entre diferentes, conhecidos, tipos de dados que podem ser logicamente mudou de uma forma para outra.

Conversão cobre até mesmo alguns do mesmo terreno que vazamento, permitindo a conversão entre tipos de dados semelhantes.


Lembre-se que a linguagem C # tem a sua própria maneira de fazer algumas coisas.
E o subjacente .NET Framework tem sua própria maneira de fazer as coisas, para além de qualquer linguagem de programação.
(Às vezes, eles se sobrepõem em suas intenções.)

Pense lançando como uma característica C # nível linguagem que é mais limitado na natureza, e de conversão através da classe System.Convert como um dos muitos mecanismos disponíveis no quadro .NET para valores converter entre diferentes tipos.

Não há um elenco padrão de string para int em .NET. Você pode usar int.Parse () ou int.TryParse () para fazer isso. Ou, como você fez, você pode usar Convert.ToInt32 ().

No entanto, no seu exemplo, por que um ToString () e, em seguida, convertê-lo de volta para um int em tudo? Você poderia simplesmente armazenar o int na sessão e recuperá-lo da seguinte forma:

int i = Session["name1"];

Apenas uma breve extra: em diferentes circunstâncias (por exemplo, se você está convertendo um duplo, & c para um Int32) você pode também querer se preocupar com arredondamento ao escolher entre estes dois. Convert.Int32 usará arredondamento do banqueiro ( MSDN ); (Int) só vai truncar para um inteiro.

1) C # é tipo de linguagem seguro e não permite que você para string atribuir ao número

2) segundo caso analisa a cadeia para nova variável. No seu caso, se a sessão é sessão ASP.NET que você não tem a cadeia de loja lá e convertê-lo de volta ao recuperar

int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];

Convert.ToInt32

    return int.Parse(value, CultureInfo.CurrentCulture);

mas (int) é o tipo de elenco, então (int) "2" não irá funcionar desde que você não pode lançar string para int. mas você pode analisá-lo como Convert.ToInt32 fazer

A diferença é que o primeiro trecho é um elenco e o segundo é um convertido. Embora, eu acho que talvez o erro do compilador está fornecendo mais confusão aqui por causa da redação. Talvez seria melhor se ele disse que "não pode lançar tipo 'string' para 'int'.

Esta é antiga, mas uma outra diferença é que (int) não arredonda os números em caso de você ter um duplo ej: 5,7 a ouput usando (int) será de 5 e se você usar Convert.ToInt () o número será lançado rodada a 6.

Esta já é discutido, mas eu quero compartilhar um dotnetfiddle.

Se você está lidando com operações aritméticas e usando float, decimal, double e assim por diante, você deve usar melhor Convert.ToInt32 ().

using System;

public class Program
{
  public static void Main()
  {
    double cost = 49.501;
    Console.WriteLine(Convert.ToInt32(cost));
    Console.WriteLine((int)cost);
  }
}

saída

50
49

https://dotnetfiddle.net/m3ddDQ

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