Будет ли компилятор c # выполнять несколько неявных преобразований для перехода из одного типа в другой? - PullRequest
4 голосов
/ 23 октября 2009

Допустим, у вас есть класс, подобный следующему:

public sealed class StringToInt { 
    private string _myString; 
    private StringToInt(string value) 
    { 
        _myString = value; 
    } public static implicit operator int(StringToInt obj) 
    { 
        return Convert.ToInt32(obj._myString); 
    } 
    public static implicit operator string(StringToInt obj) 
    { 
        return obj._myString; 
    } 
    public static implicit operator StringToInt(string obj) 
    { 
        return new StringToInt(obj); 
    } 
    public static implicit operator StringToInt(int obj) 
    { 
        return new StringToInt(obj.ToString()); 
    } 
}

Сможете ли вы написать код, подобный следующему:

MyClass.SomeMethodThatOnlyTakesAnInt(aString);

без указания того, что нет неявного приведения из строки в int?

[Да, я мог бы проверить это сам, но я подумал, что выложу это и посмотрю, что скажут все гуру]

Ответы [ 4 ]

10 голосов
/ 23 октября 2009

Никакой C # не вызовет более одного определенного неявного преобразования. Из раздела 6.4.3 спецификации C #:

Для оценки пользовательского преобразования никогда не требуется более одного пользовательского или отмененного оператора преобразования. Другими словами, преобразование из типа S в тип T никогда не выполнит пользовательское преобразование из S в X, а затем выполнит пользовательское преобразование из X в T.

1 голос
/ 23 октября 2009

Это не похоже на работу. Требуется как минимум одно явное приведение. Ну да ладно ...

1 голос
/ 23 октября 2009

Я вполне уверен, что это невозможно в C # 3.0. Разделы в ссылка , которая охватывает преобразования, составляет 6.4. А именно, 6.4.4 «Пользовательские неявные преобразования».

В нем говорится только о преобразованиях из S-> T (а не S-> T-> U), которые охватывают такие случаи, как:

StringToInt _t = "foo";
int t = _t;

и

int t = (StringToInt)"foo";

Там, где в обоих случаях используется только S-> T (дважды).

Я почти уверен, что это невозможно в C # 3.0. Разрешение S-> T-> U потребует гораздо больше работы, выполняемой средством сопоставления типов, по крайней мере, в соответствии с указанным алгоритмом.

0 голосов
/ 23 октября 2009

опечатки в вашем фрагменте:

public StringToInt(string value)
{
    _myString = value;
}
public static implicit operator int(StringToInt obj)
{
    return Convert.ToInt32(obj._myString);
}
public static implicit operator string(StringToInt obj)
{
    return obj._myString;
}

Если aString имеет тип StringToInt, ваше использование должно работать.

...