Considere o seguinte código:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
Qual é a diferença entre os três tipos de elenco (ok, o terceiro não é um elenco, mas você tem a intenção). Qual deles deve ser preferido?
string s = Convert.ToString(o)
:; 5º:string s = $"{o}"
(ou equivalentemente ostring.Format
formulário para C # anterior)Respostas:
Lança InvalidCastException se
o
não for umstring
. Caso contrário, atribuio
as
, mesmo queo
sejanull
.Atribui
null
as
seo
não é umstring
ou seo
énull
. Por esse motivo, você não pode usá-lo com tipos de valor (o operador nunca poderá retornarnull
nesse caso). Caso contrário, atribuio
as
.Causa uma NullReferenceException se
o
fornull
. Atribui o que quer queo.ToString()
retornes
, independentemente do tipoo
.Use 1 para a maioria das conversões - é simples e direto. Costumo quase nunca usar 2, pois se algo não for do tipo certo, normalmente espero que ocorra uma exceção. Eu só vi a necessidade desse tipo de funcionalidade de retorno nulo com bibliotecas mal projetadas que usam códigos de erro (por exemplo, retorno nulo = erro, em vez de usar exceções).
3 não é um elenco e é apenas uma invocação de método. Use-o para quando você precisar da representação em sequência de um objeto que não seja sequência.
fonte
string s = (string)o;
Use quando algo definitivamente deve ser a outra coisa.string s = o as string;
Use quando algo puder ser a outra coisa.string s = o.ToString();
Use quando você não se importa com o que é, mas você apenas deseja usar a representação de string disponível.fonte
Realmente depende se você sabe se
o
é uma string e o que deseja fazer com ela. Se seu comentário significa queo
realmente é uma sequência, eu prefiro o(string)o
elenco direto - é improvável que falhe.A maior vantagem de usar a conversão direta é que, quando falha, você recebe uma InvalidCastException , que informa praticamente o que deu errado.
Com o
as
operador, seo
não for uma sequência,s
está definido comonull
, o que é útil se você não tiver certeza e quiser testars
:No entanto, se você não executar esse teste, usará
s
mais tarde e lançará uma NullReferenceException . Eles tendem a ser mais comuns e muito mais difíceis de rastrear quando ocorrem na natureza, pois quase todas as linhas referenciam uma variável e podem jogar uma. Por outro lado, se você estiver tentando converter para um tipo de valor (qualquer primitivo ou estrutura como DateTime ), precisará usar a conversão direta -as
isso não funcionará.No caso especial de conversão para uma string, todo objeto possui um
ToString
, portanto seu terceiro método pode ser bom seo
não for nulo e você acha que oToString
método pode fazer o que você deseja.fonte
as
com tipos de valores anuláveis . IEo as DateTime
não vai funcionar, maso as DateTime?
vai ...if (s is string)
?is
ing, você terá que lançar novamente de qualquer maneira, para ter o is e depois um hard cast. Por alguma razão, aas
verificação nula e me pareceu melhor.Se você já sabe para qual tipo ele pode transmitir, use um estilo C:
Observe que apenas com uma conversão no estilo C você pode executar coerção de tipo explícita.
Se você não sabe se é o tipo desejado e vai usá-lo se for, use como palavra-chave:
Observe que as chamadas não serão chamadas para nenhum operador de conversão de tipo. Somente será não nulo se o objeto não for nulo e nativamente do tipo especificado.
Use ToString () para obter uma representação de string legível por humanos de qualquer objeto, mesmo que não possa ser convertido em string.
fonte
A palavra-chave as é boa no asp.net quando você usa o método FindControl.
Isso significa que você pode operar a variável digitada em vez de precisar convertê-la
object
como faria com uma conversão direta:Não é uma coisa enorme, mas salva linhas de código e atribuição de variáveis, além de ser mais legível
fonte
'as' é baseado em 'is', que é uma palavra-chave que verifica em tempo de execução se o objeto é polimorfricamente compatível (basicamente se é possível fazer uma conversão) e retorna nulo se a verificação falhar.
Estes dois são equivalentes:
Usando 'como':
Usando 'é':
Pelo contrário, o elenco do estilo c é feito também em tempo de execução, mas lança uma exceção se o elenco não puder ser feito.
Apenas para adicionar um fato importante:
A palavra-chave 'as' funciona apenas com tipos de referência. Você não pode fazer:
Nesses casos, você deve usar o casting.
fonte
2 é útil para converter para um tipo derivado.
Suponha que a é um animal:
vai ter um alimentado com um mínimo de moldes.
fonte
De acordo com experimentos realizados nesta página: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(esta página está apresentando alguns erros de "referenciador ilegal" às vezes, então atualize apenas)
A conclusão é que o operador "as" é normalmente mais rápido que uma conversão. Às vezes, muitas vezes mais rápido, às vezes apenas mais rápido.
Eu costumo dizer que "como" também é mais legível.
Portanto, como é mais rápido e "mais seguro" (não emitirá exceção) e possivelmente mais fácil de ler, eu recomendo usar "como" o tempo todo.
fonte
"(string) o" resultará em InvalidCastException, pois não há conversão direta.
"o as string" resultará em s sendo uma referência nula, em vez de uma exceção lançada.
"o.ToString ()" não é um elenco de nenhum tipo per se, é um método implementado por objeto e, portanto, de uma maneira ou de outra, por todas as classes em .net que "fazem algo" com a instância de a classe em que é chamada e retorna uma string.
Não esqueça que, para converter em string, também há Convert.ToString (someType instanceOfThatType), em que someType é um de um conjunto de tipos, essencialmente os tipos base das estruturas.
fonte
Todas as respostas dadas são boas, se eu puder adicionar algo: Para usar diretamente os métodos e propriedades da string (por exemplo, ToLower), você não pode escrever:
você só pode escrever:
mas você poderia escrever:
A
as
opção é mais legível (pelo menos na minha opinião).fonte
(o as string).ToLower()
vez dos vários colchetes confusos.É preferível, pois evita a penalidade de desempenho da dupla fundição.
fonte
Parece que os dois são conceitualmente diferentes.
Fundição Direta
Os tipos não precisam ser estritamente relacionados. Ele vem em todos os tipos de sabores.
Parece que o objeto será convertido em outra coisa.
Operador AS
Os tipos têm um relacionamento direto. Como em:
Parece que você vai manipular o objeto de uma maneira diferente.
Amostras e IL
fonte
Gostaria de chamar a atenção para as seguintes especificidades do como operador:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
fonte
Ao tentar obter a representação em string de qualquer coisa (de qualquer tipo) que possa ser potencialmente nula, prefiro a linha de código abaixo. É compacto, invoca ToString () e lida corretamente com nulos. Se o for nulo, s conterá String.Empty.
fonte
Como ninguém o mencionou, o mais próximo de instanceOf to Java por palavra-chave é o seguinte:
fonte
Use conversão direta
string s = (string) o;
se, no contexto lógico do seu aplicativo,string
for o único tipo válido. Com essa abordagem, você obteráInvalidCastException
e implementará o princípio de Fail-fast . Sua lógica será protegida de passar ainda mais o tipo inválido ou obter o NullReferenceException se for utilizadoas
.Se a lógica espera que vários tipos diferentes sejam expressos,
string s = o as string;
marque-anull
ou use ois
operador.Um novo recurso interessante apareceu no C # 7.0 para simplificar o elenco e verificar se há uma correspondência de padrões :
fonte
As duas formas a seguir de conversão de tipo (conversão) são suportadas em C #:
|
(Cv
• Converta o tipo estático de v em c na expressão fornecida
• Só é possível se o tipo dinâmico de v for c ou um subtipo de c
• Caso contrário, uma InvalidCastException é lançada
|
v como C
• Variante não fatal de (c) v
• Assim, converta o tipo estático de v em c na expressão fornecida
• Retorna nulo se o tipo dinâmico de v não for c ou um subtipo de c
fonte