?: и ref return
От: _NN_ www.nemerleweb.com
Дата: 16.12.19 18:12
Оценка:
Почему этот код компилируется

class A
{
    bool p;

    ref bool? f(ref bool? z)
    {
        if (p) { return ref z; }
        else return ref z;
    }
}


А замена на ?: нет ?
class A
{
    bool p;

    ref bool? f(ref bool? z)
    {
        return p ? ref z : ref z; // CS8150    By-value returns may only be used in methods that return by value    

    }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: ?: и ref return
От: nikov США http://www.linkedin.com/in/nikov
Дата: 16.12.19 18:37
Оценка: 90 (3)
Здравствуйте, _NN_, Вы писали:

_NN>
_NN>class A
_NN>{
_NN>    bool p;

_NN>    ref bool? f(ref bool? z)
_NN>    {
_NN>        return p ? ref z : ref z; // CS8150    By-value returns may only be used in methods that return by value    

_NN>    }
_NN>}
_NN>


По той же причине, почему `return ref z` компилируется, а `return z` нет (несмотря на то, что параметр `z` уже объявлен, как `ref`) — если ты хочешь вернуть ссылку, а не значение, то надо явно писать `return ref (p ? ref z : ref z)`.

Вообще-то приоритет операторов позволяет написать это и без скобок: `return ref p ? ref z : ref z`, но, по-моему, это читается гораздо хуже.
Re[2]: ?: и ref return
От: nikov США http://www.linkedin.com/in/nikov
Дата: 16.12.19 18:59
Оценка:
Здравствуйте, nikov, Вы писали:

N>По той же причине, почему `return ref z` компилируется, а `return z` нет (несмотря на то, что параметр `z` уже объявлен, как `ref`) — если ты хочешь вернуть ссылку, а не значение, то надо явно писать `return ref (p ? ref z : ref z)`.

N>Вообще-то приоритет операторов позволяет написать это и без скобок: `return ref p ? ref z : ref z`, но, по-моему, это читается гораздо хуже.

Замечу на всякий случай, что токен `ref` — это не оператор, а часть специальной синтаксической конструкции, которая может использоваться в весьма ограниченных контекстах. Например, нельзя написать `return (ref z)` или `p ? (ref x) : (ref y)`.
Re[2]: ?: и ref return
От: _NN_ www.nemerleweb.com
Дата: 16.12.19 19:22
Оценка:
Здравствуйте, nikov, Вы писали:

N>По той же причине, почему `return ref z` компилируется, а `return z` нет (несмотря на то, что параметр `z` уже объявлен, как `ref`)

Как раз эта часть вписалась в логику легко.

N> — если ты хочешь вернуть ссылку, а не значение, то надо явно писать `return ref (p ? ref z : ref z)`.

Ясно.
Заодно придмалось как один 'ref' меняет смысл метода.
using System;

class P
{
    public ref bool f(ref bool z, ref bool q)
    {
        z = ref q;
        return ref z;
    }

    public ref bool g(ref bool z, ref bool q)
    {
        z = q;
        return ref z;
    }
}

class Q
{
    static void F()
    {
        bool a = true;
        bool b = false;
        ref var r = ref new P().f(ref a, ref b);
        b = true;

        Console.WriteLine(r);
    }

    static void G()
    {
        bool a = true;
        bool b = false;
        ref var r = ref new P().g(ref a, ref b);
        b = true;

        Console.WriteLine(r);
    }

    static void Main()
    {
        F();
        G();
    }
}


N>Вообще-то приоритет операторов позволяет написать это и без скобок: `return ref p ? ref z : ref z`, но, по-моему, это читается гораздо хуже.

Осталось ещё добавить туда ??= !
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: ?: и ref return
От: nikov США http://www.linkedin.com/in/nikov
Дата: 16.12.19 19:40
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>Заодно придмалось как один 'ref' меняет смысл метода.


Ну, это всегда можно было сделать:

static class Program
{
    static void Foo(int x) => throw null;
    static void Foo(ref int x) => throw null;

    static void Main()
    {
        int x = 1;
        Foo(x);
        Foo(ref x);
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.