странный эффект со ссылками и List
От: jyuyjiyuijyu  
Дата: 09.03.14 22:31
Оценка:
Всем привет

столкнулся со странным эффектом

написав такой код ожидал изменить внутри функции значения хендлов в списке
но на выходе из функции значения хендлов в списке неизменны...

странно на какой же тогда хендл я беру ссылку ?

спасибо

void f(Object^% e1, Object^% e2)
{
    e2 = e1;
}

int main(cli::array<String^>^ args)
{
    List<Object^> l;
    l.Add(gcnew Object);
    l.Add(gcnew Object);

    f(l[0], l[1]);
}
Re: странный эффект со ссылками и List
От: Igorxz  
Дата: 10.03.14 05:14
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>Всем привет


J>столкнулся со странным эффектом


J>написав такой код ожидал изменить внутри функции значения хендлов в списке

J>но на выходе из функции значения хендлов в списке неизменны...

J>странно на какой же тогда хендл я беру ссылку ?


J>спасибо


J>
J>void f(Object^% e1, Object^% e2)
J>{
J>    e2 = e1;
J>}

J>int main(cli::array<String^>^ args)
J>{
J>    List<Object^> l;
J>    l.Add(gcnew Object);
J>    l.Add(gcnew Object);

J>    f(l[0], l[1]);
J>}
J>


вот сюда — void f(Object^% e1, Object^% e2) — приходят tracking reference объектов не в листе. это tracking reference временных ссылок (или указателей) на объекты. вот этих: gcnew Object(). в листе прямой доступ к нижележащему массиву закрыт, поэтому в лоб так сделать не выйдет.
что бы трюк прошел, лист должен: давать прямой доступ к нижележащему массиву, либо возвращать tracking reference через свойство доступа к элементу массива. наверно можно через рефлексию как-нибудь получить — но это не спортивно.
Re[2]: странный эффект со ссылками и List
От: jyuyjiyuijyu  
Дата: 10.03.14 05:28
Оценка:
Здравствуйте, Igorxz, Вы писали:

вот с массивом работает а со списком не хочет... неочевидная хрень


void f(Object^% e1, Object^% e2)
{
    e2 = e1;
}

int main(cli::array<String^>^ args)
{
    auto l = gcnew array<Object^>(2) { gcnew Object, gcnew Object };
    
    f(l[0], l[1]);
}
Re: странный эффект со ссылками и List
От: _NN_ www.nemerleweb.com
Дата: 10.03.14 07:49
Оценка: 4 (1)
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>Всем привет


Этот код аналогичен шарповскому:
static int main(string[] args)
{
    List<object> i = new List<object>();
    i.Add(new object());
    i.Add(new object());
    object obj = i[1];
    object obj2 = i[0];
    f(ref obj2, ref obj);
    return 0;
}


А с массивом будет:
    object[] i = new object[]
    {
        new object(),
        new object()
    };
    f(ref i[0], ref i[1]);
    return 0;


Очевидно с массивом работает потому как есть прямой доступ к элементам, а в случае со списком есть только свойство индексера где 'ref' уже не применить.

Ну или возьмем свой класс с operator[] :
ref class A
{
public:
    Object^ operator[](int i)
    {
        return i;
    }
};

void f(Object^% e1, Object^% e2)
{
    e2 = e1;
}

int main(cli::array<String^>^ args)
{
    auto l = gcnew A();

    f(l[0], l[1]);
}


Так создается временная переменная.
Но если вернуть Object^% , то все возможно
Правда через unsafe конечно.

ref class A
{
public:
    Object^% operator[](int i)
    {
        return gcnew Object();
    }
};

void f(Object^% e1, Object^% e2)
{
    e2 = e1;
}

int main(cli::array<String^>^ args)
{
    auto l = gcnew A();

    f(l[0], l[1]);
}


internal class A
{
    public unsafe object* op_Subscript(int i)
    {
        object j = new object();
        return ref j;
    }
}

internal static int main(string[] args)
{
    A i = new A();
    f(i.op_Subscript(0), i.op_Subscript(1));
    return 0;
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: странный эффект со ссылками и List
От: drol  
Дата: 10.03.14 13:02
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>неочевидная хрень


Вы язык не перепутали, случайно ? Вы про C++ вообще-то говорите. В котором жесточайшая перегрузка операций является одной из ключевых фич.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.