Não é possível converter implicitamente o tipo 'X' para 'string' - quando e como decide que “não pode”?
-
09-09-2019 - |
Pergunta
Agora eu estou tendo com Guid
s.
Eu certamente lembrar que todo o código em alguns lugares esta conversão implícita trabalha, em outros, não. Até agora não consigo ver o padrão.
Como o compilador decide quando não pode? Quer dizer, o método tipo Guid.ToString()
está presente, não-lo chamado sempre que esta transformação é necessário é?
Alguém por favor pode me dizer em que circunstâncias essa transformação é feita automaticamente e quando eu tenho que myInstance.ToString()
chamada explicitamente?
Solução
Em suma, quando há um operador de conversão implícita ou explícita definido:
class WithImplicit {
public static implicit operator string(WithImplicit x) {
return x.ToString();}
}
class WithExplicit {
public static explicit operator string(WithExplicit x) {
return x.ToString(); }
}
class WithNone { }
class Program {
static void Main() {
var imp = new WithImplicit();
var exp = new WithExplicit();
var none = new WithNone();
string s1 = imp;
string s2 = (string)exp;
string s3 = none.ToString();
}
}
Outras dicas
Não, não há nenhuma conversão implícita de GUID
para String
, de modo que não funciona em qualquer lugar em tudo no código.
Ele só funciona onde há uma conversão explícita, mas a conversão pode não ser muito visível. Por exemplo, quando você concatenar strings:
string id = "--" + guidValue + " : " + num;
Isso pode parecer uma conversão implícita de GUID
para String
, mas não é. O código que é gerado na verdade se parece com isso:
string id = String.Concat(new object[] { "--", guidValue, " : ", num });
Todos os operandos são lançados para o tipo Object
e colocados em uma matriz. O método String.Concat
em seguida, chama o método ToString
para cada item na matriz para obter a representação de cadeia para eles.
O único lugar onde você efetivamente não precisa chamar ToString () você mesmo é quando concatenar strings.
Guid g;
int i;
string s = "Hello "+g+' '+i;
Depois, há algumas situações em que a chamada é feita pelo .NET Framework, como em String.Format () .
Para além de que, o compilador só vai converter um tipo, se é conhecido por ser compatível (por exemplo, base ou classe implementando uma interface ou por meio de um operador de conversão explicitamente codificados). Quando você usa um elenco e o compilador sabe que os tipos não pode ser compatível (por exemplo, não na mesma linha de herança, e não as interfaces), que também irá dizer que não pode convertê-lo. O mesmo vale para parâmetros de tipo genérico.