Всем привет
столкнулся со странным эффектом
написав такой код ожидал изменить внутри функции значения хендлов в списке
но на выходе из функции значения хендлов в списке неизменны...
странно на какой же тогда хендл я беру ссылку ?
спасибо
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]);
}
Здравствуйте, 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 через свойство доступа к элементу массива. наверно можно через рефлексию как-нибудь получить — но это не спортивно.
Здравствуйте, 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]);
}
Здравствуйте, 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;
}