Не можете неявно преобразовать тип «X» в «строку» - когда и как он решает, что он «не может»? - PullRequest
16 голосов
/ 15 апреля 2009

Прямо сейчас у меня это с Guid с.

Я, конечно, помню, что во всем коде в некоторых местах это неявное преобразование работает, в других - нет. До сих пор я не вижу картины.

Как компилятор решает, когда он не может? Я имею в виду, метод типа Guid.ToString() присутствует, разве он не вызывается всякий раз, когда необходимо это преобразование?

Может кто-нибудь сказать мне, при каких обстоятельствах это преобразование выполняется автоматически, и когда мне нужно явно позвонить myInstance.ToString()?

Ответы [ 3 ]

32 голосов
/ 15 апреля 2009

Короче говоря, когда определен неявный или явный оператор преобразования:

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();
    } 
}
4 голосов
/ 15 апреля 2009

Нет, неявное преобразование из GUID в String отсутствует, поэтому в коде вообще ничего не работает.

Работает только там, где есть явное преобразование, но преобразование может быть не очень заметным. Например, когда вы объединяете строки:

string id = "--" + guidValue + " : " + num;

Это может выглядеть как неявное преобразование из GUID в String, но это не так. Код, который генерируется на самом деле выглядит так:

string id = String.Concat(new object[] { "--", guidValue, " : ", num });

Все операнды приводятся к типу Object и помещаются в массив. Затем метод String.Concat вызывает метод ToString для каждого элемента в массиве, чтобы получить для них строковое представление.

4 голосов
/ 15 апреля 2009

Единственное место, где вам фактически не нужно вызывать ToString () самостоятельно, - это конкатенация строк.

Guid g;
int i;
string s = "Hello "+g+' '+i;

Тогда есть некоторые ситуации, когда вызов выполняется .NET Framework, например, String.Format () .

Кроме этого, компилятор будет преобразовывать тип только в том случае, если известно, что он совместим (например, базовый класс или реализация интерфейса, либо с помощью явно закодированного оператора преобразования). Когда вы используете приведение, и компилятор знает, что типы не могут быть совместимы (например, не в одной строке наследования и не в интерфейсах), он также скажет, что не может преобразовать его. То же самое касается параметров универсального типа.

...