Невозможно неявно преобразовать тип "X" в "string" - когда и как он решает, что он "не может"?
Сейчас у меня это с Guid
s.
Я, конечно, помню, что во всем коде в некоторых местах это неявное преобразование работает, в других - нет. До сих пор я не вижу шаблон.
Как компилятор решает, когда он не может? Я имею в виду, что существует метод типа Guid.ToString()
, не называется ли его всякий раз, когда это преобразование необходимо?
Может кто-нибудь, пожалуйста, скажите мне, при каких обстоятельствах это преобразование выполняется автоматически и когда я должен явно называть myInstance.ToString()
?
Ответы
Ответ 1
Короче говоря, когда имеется явный или явный оператор преобразования:
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();
}
}
Ответ 2
Единственное место, где вам фактически не нужно вызывать ToString(), - это объединение строк.
Guid g;
int i;
string s = "Hello "+g+' '+i;
Затем возникают ситуации, когда вызов выполняется .NET Framework, например, в String.Format().
Кроме этого, компилятор будет преобразовывать только тип, если он известен как совместимый (например, базовый класс или реализация интерфейса или через явно закодированный оператор преобразования). Когда вы используете трансляцию, и компилятор знает, что типы не могут быть совместимы (например, не в одной строке наследования, а не в интерфейсах), он также скажет, что он не может ее преобразовать. То же самое относится к параметрам типового типа.
Ответ 3
Нет, нет никакого неявного преобразования от GUID
до String
, поэтому в коде вообще ничего не работает.
Он работает только там, где есть явное преобразование, но преобразование может быть не очень заметным. Например, когда вы объединяете строки:
string id = "--" + guidValue + " : " + num;
Это может выглядеть как неявное преобразование от GUID
до String
, но это не так. Созданный код на самом деле выглядит следующим образом:
string id = String.Concat(new object[] { "--", guidValue, " : ", num });
Все операнды передаются в тип Object
и помещаются в массив. Затем метод String.Concat
вызывает метод ToString
для каждого элемента массива, чтобы получить строковое представление для них.