Ambiguous user defined conversions
От: Qbit86 Кипр
Дата: 30.04.19 15:37
Оценка:
Добрый вечер!

Почему не компилируется неявная пользовательская конверсия в контексте кортежей? Какой пункт спецификации это описывает?
Если на то есть уважительные причины, то почему тогда компилируются другие пользовательские конверсии?

internal readonly struct Pair
{
    public Pair(string name, string type)
    {
        Name = name;
        Type = type;
    }

    internal string Name { get; }
    internal string Type { get; }

    public override string ToString() => $"{Name}: {Type}";

    public static implicit operator Pair((string, int) t) => new Pair(t.Item1, "int");

    public static implicit operator Pair((string, uint) t) => new Pair(t.Item1, "uint");
}

internal static class Program
{
    private static void Render(Pair pair)
    {
        System.Console.WriteLine(pair);
    }

    private static void Main()
    {
        const uint u = 23;
        Render(("u", u)); // u: uint

        const int m = -1;
        Render(("-", m)); // -: int

        const int i = 42;
        Render(("i", i)); // Error CS0457

        var t = ("t", i);
        Render(t); // t: int
    }
}


Текст ошибки:

Ambiguous user defined conversions 'Pair.implicit operator Pair((string, int))' and 'Pair.implicit operator Pair((string, uint))' when converting from '(string, int i)' to 'Pair'

Глаза у меня добрые, но рубашка — смирительная!
Отредактировано 30.04.2019 15:39 Qbit86 . Предыдущая версия .
Re: Ambiguous user defined conversions
От: _NN_ www.nemerleweb.com
Дата: 30.04.19 20:10
Оценка: 6 (1)
Смотреть тут:
https://stackoverflow.com/questions/9017363/ambiguous-method-overloading
https://stackoverflow.com/questions/9008637/why-does-this-implicit-conversion-from-int-to-uint-work/9008765#9008765

В общем фишка нужна, чтобы не надо было писать тип явно для значений умещающихся в byte, short:
const int a = 1;

byte b = a; // OK


Integer constant conversions are treated as very special by the C# language; here's section 6.1.9 of the specification:

A constant expression of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type. A constant expression of type long can be converted to type ulong, provided the value of the constant expression is not negative.

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Integer constant conversions
От: Qbit86 Кипр
Дата: 30.04.19 21:14
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В общем фишка нужна, чтобы не надо было писать тип явно для значений умещающихся в byte, short


Это не объясняет двух вещей.
1) В последнем тесте вывод типа и выбор перегрузки выполнился корректно, как ожидается:
var t = ("t", i);
Render(t); // t: int

При этом тот же тип выводится ровно так же при прямой подстановке в вызов, только в случае этой прямой подстановки почему-то возникает неоднозначность.
const int i = 42;
Render(("i", i)); // Error CS0457


2) Аналогичный пример без кортежей успешно компилируется, хотя к нему применимы те же рассуждения про конверсии из int:
internal readonly struct Pair
{
    public Pair(string name, string type)
    {
        Name = name;
        Type = type;
    }

    internal string Name { get; }
    internal string Type { get; }

    public override string ToString() => $"{Name}: {Type}";

    public static implicit operator Pair(int value) => new Pair(value.ToString(), "int");

    public static implicit operator Pair(uint value) => new Pair(value.ToString(), "uint");
}

internal static class Program
{
    private static void Render(Pair pair)
    {
        System.Console.WriteLine(pair);
    }

    private static void Main()
    {
        const uint u = 23;
        Render(u); // 23: uint
        Render(23u); // 23: uint

        const int m = -1;
        Render(m); // -1: int
        Render(-1); // -1: int

        const int i = 42;
        Render(i); // 42: int
        Render(42); // 42: int
    }
}
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: Integer constant conversions
От: _NN_ www.nemerleweb.com
Дата: 01.05.19 16:22
Оценка:
Здравствуйте, Qbit86, Вы писали:

Думаю тут нужен nikov или Эрик Липперт.
Не удивлюсь если просто в компиляторе забыли реализовать это для кортежей.
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.