49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318

Структура в List<>, "Не удалось изменить возвращаемое значение"

30.06.2012, 14:14. Показов 27724. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace
{
   struct  STRUCT
            {
                 internal float a;
                 internal float b;
            }
   class Storage
           {
                 List<STRUCT> _Array;
           }
           void Function(float b)
           {
                 //всё внимание на присваивание
                 _Array[0].a=b;
           }
}
Одним словом при таких манипуляциях вот такая ошибка

Ошибка 1 Не удалось изменить возвращаемое значение для
//
"System.Collections.Generic.List<Name.ST RUCT>.this[int]", т.к. оно не является переменной
//
Я честно говоря ошалел от такого дела.
Кто знает как правильно организовать полный доступ к полям в структуре в таком раскладе, отзовитесь.
Если применять класс вместо структуры, то всё в норме.
Пробовал организовать метод в структуре для доступа к полю, копилятор молчит, но изменений во время выполнения не происходит.
Может я забыл как дышать?
Спасибо всем за любую помощь.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.06.2012, 14:14
Ответы с готовыми решениями:

Не удалось изменить возвращаемое значение для List<T>.this[int]
listStructSelected.byteStatus = getStatus(); Ошибка: Ошибка 25 Не удалось изменить возвращаемое значение для...

Не удалось изменить возвращаемое значение, т.к. оно не является переменной
Привет такая проблема копировал код на движение персонажа у одного блогера у него все работает у меня ошибка код наверное 2017г . ответ...

Не удалось изменить возвращаемое значение "Transform.position", т.к. оно не является переменной
Не удалось изменить возвращаемое значение &quot;Transform.position&quot;, т.к. оно не является переменной. Ошибка на 13 строке. Просьба помочь! ...

16
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
30.06.2012, 14:31
Структуры передаются и возвращаются по значению.
Когда вы написали _Array[0], это вернуло полную структуру из списка.
И компилятор предостерег вас, что вы меняете локальную копию, вместе того чтобы менять структуру в листе.

Чтобы менять одно поле в списке структур придется заводить локальную переменную, туда записывать полученное из списка значение.
Потом менять поле в структуре, и записывать локальную переменную назад в список.
C#
1
2
3
var str = _Array[0];
str.a=b;
_Array[0] = str;
4
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
30.06.2012, 14:34  [ТС]
То есть листу я могу присвоить лишь полную структуру.
Логично, я думал об этом, но потом вылетело из головы.
Спасибо большое за оперативный ответ.
0
 Аватар для bodynar
345 / 307 / 135
Регистрация: 14.03.2015
Сообщений: 1,158
Записей в блоге: 1
17.03.2015, 14:43
Столкнулся с аналогичной проблемой, но для динамического поля.
Имеется структурный список (studentInfo - структура). В метод передается название поля структуры (существующего поля) и новое значение.
Воспользовался вашим решением, но все также не получаю изменений.
При прямом обращении к полю пишет ошибку, описанную выше.
C#
1
2
3
4
5
6
7
8
9
10
11
12
public static List<studentInfo> students = new List<studentInfo>();
 
static public void setStudentInfo(studentInfo student, string fieldName, object value)
        {
            studentInfo StudentWithNewInfo = student;
            Debug.WriteLine("1. "+StudentWithNewInfo.firstName + " " + StudentWithNewInfo.middleName + " " + StudentWithNewInfo.secondName);
            typeof(studentInfo).GetField(fieldName).SetValue(StudentWithNewInfo, value);
            Debug.WriteLine("2. " + StudentWithNewInfo.firstName + " " + StudentWithNewInfo.middleName + " " + StudentWithNewInfo.secondName);
            students[students.IndexOf(student)] = StudentWithNewInfo;
            Debug.WriteLine("3. " + students[students.IndexOf(student)].firstName + " " + students[students.IndexOf(student)].middleName + " " + students[students.IndexOf(student)].secondName);
           
}
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.03.2015, 14:50
Цитата Сообщение от bodynar Посмотреть сообщение
C#
1
.SetValue(StudentWithNewInfo, value);
SetValue — метод, а
Цитата Сообщение от turbanoff Посмотреть сообщение
Структуры передаются и возвращаются по значению.
Потому в метод передается копия, она же и изменяется, да еще и с запаковкой.

Попробуйте запаковать явно, а потом уже передавать:
C#
1
2
3
4
5
6
7
8
9
studentInfo StudentWithNewInfo = student;
Debug.WriteLine("1. "+StudentWithNewInfo.firstName + " " + StudentWithNewInfo.middleName + " " + StudentWithNewInfo.secondName);
 
object temp = StudentWithNewInfo;
typeof(studentInfo).GetField(fieldName).SetValue(temp, value);
StudentWithNewInfo = (studentInfo)temp;
 
Debug.WriteLine("2. " + StudentWithNewInfo.firstName + " " + StudentWithNewInfo.middleName + " " + StudentWithNewInfo.secondName);
students[students.IndexOf(student)] = StudentWithNewInfo;
Еще один аргумент в пользу того, чтобы использовать структуры вместо классов исключительно там, где они действительно нужны и/или полезны.
В данном случае смысла использовать структуру как-то не видно.

И да, замените рефлексию на нормальную архитектуру или на худой конец используйте какой-нибудь ExpandoObject.
1
 Аватар для bodynar
345 / 307 / 135
Регистрация: 14.03.2015
Сообщений: 1,158
Записей в блоге: 1
17.03.2015, 15:12
Цитата Сообщение от kolorotur Посмотреть сообщение
В данном случае смысла использовать структуру как-то не видно.
Соглашусь с вами, но, увы, в моем задании использование структуры обязательно.
Спасибо, работает теперь как надо.
Но все же не могу понять: Мы передаем копию объекта из списка, изменяем у него поле и обновляем этот объект в списке - почему это не есть правильно?
0
18 / 18 / 9
Регистрация: 23.02.2015
Сообщений: 86
17.03.2015, 15:17
если хотите через метод изменить структуру, то это можно с помощью интерфейсов сделать
C#
1
interface IChangeStructValue{void Change(int i, int j);}
потом создать объект в который передать метод с аргументами
C#
1
IChangeStructValue x = (MyStruct)myList[0]; x.Change(1,1);
Добавлено через 4 минуты
и реализация метода
C#
1
struct myStruct:IChangeStructValue{ public int x{get;set;} public int y{get;set;}public void Change(int x, int y){this.x=x;this.y=y}}
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.03.2015, 15:21
Цитата Сообщение от bodynar Посмотреть сообщение
Мы передаем копию объекта из списка, изменяем у него поле и обновляем этот объект в списке - почему это не есть правильно?
Полужирным выделена неправильная часть — вы изменяете поле не у копии структуры из списка, а у копии копии структуры из списка, потому что передаете эту копию в метод SetValue, а при передаче структуры в метод создается копия и она уже передается.

Добавлено через 1 минуту
Цитата Сообщение от Баир Посмотреть сообщение
C#
1
IChangeStructValue x = (MyStruct)myList[0]; x.Change(1,1);
То же самое будет: из списка извлекается копия, да еще и запаковывается.
0
18 / 18 / 9
Регистрация: 23.02.2015
Сообщений: 86
17.03.2015, 15:28
Цитата Сообщение от bodynar Посмотреть сообщение
Но все же не могу понять: Мы передаем копию объекта из списка, изменяем у него поле и обновляем этот объект в списке - почему это не есть правильно?
вот пример их рихтера
Далее p упаковывается в третий раз — o ссылается на упакованный объект типа
Point. При третьем обращении к WriteLine снова выводится (2, 2), что опять
вполне ожидаемо. И наконец, я обращаюсь к методу Change для изменения полей
в упакованном объекте типа Point. Между тем Object (тип переменной o) ничего
не «знает» о методе Change, так что сначала нужно привести o к Point. При таком
приведении типа o распаковывается, и поля упакованного объекта типа Point
копируются во временный объект типа Point в стеке потока. Поля m_x и m_y этого
временного объекта устанавливаются равными 3, но это обращение к Change не
влияет на упакованный объект Point. При обращении к WriteLine снова выводится
(2, 2). Для многих разработчиков это оказывается неожиданным.

Добавлено через 3 минуты
Цитата Сообщение от kolorotur Посмотреть сообщение
То же самое будет: из списка извлекается копия, да еще и запаковывается.
а если так
C#
1
Object o = myList[0];((IChangeStructValue) o).Change(5, 5);
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.03.2015, 15:32
Цитата Сообщение от Баир Посмотреть сообщение
а если так
Снова копия и снова запаковка
0
 Аватар для bodynar
345 / 307 / 135
Регистрация: 14.03.2015
Сообщений: 1,158
Записей в блоге: 1
17.03.2015, 15:33
Цитата Сообщение от kolorotur Посмотреть сообщение
Полужирным выделена неправильная часть — вы изменяете поле не у копии структуры из списка, а у копии копии структуры из списка, потому что передаете эту копию в метод SetValue, а при передаче структуры в метод создается копия и она уже передается.
Т.е. в любом случае будет создаваться копия объекта?
Возможно ли изменение поля у объекта напрямую, без создания разных копий и прочего?
0
18 / 18 / 9
Регистрация: 23.02.2015
Сообщений: 86
17.03.2015, 15:37
Цитата Сообщение от kolorotur Посмотреть сообщение
Снова копия и снова запаковка
да ну это же почти пример из книги
В последнем примере упакованный тип Point, на который ссылается o, при-
водится к типу IChangeBoxedPoint. Упаковка здесь не производится, поскольку
тип o уже упакован. Затем вызывается метод Change, который изменяет поля m_x
и m_y упакованного типа Point. Интерфейсный метод Change позволил мне изме-
нить поля упакованного объекта типа Point! Теперь при обращении к WriteLine
выводится (5, 5).
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.03.2015, 15:39
Цитата Сообщение от bodynar Посмотреть сообщение
Т.е. в любом случае будет создаваться копия объекта?
В случае использования структуры и класса List как хранилища — да, в любом.

Цитата Сообщение от bodynar Посмотреть сообщение
Возможно ли изменение поля у объекта напрямую, без создания разных копий и прочего?
Возможно, если используется другая структура данных для хранения списка структур, например массив:
C#
1
2
studentInfo[] students = new studentInfo[10];
students[0].x = 32; // OK
1
18 / 18 / 9
Регистрация: 23.02.2015
Сообщений: 86
17.03.2015, 15:39
а хотя да List это же ссылочный тип, а не значимый
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
17.03.2015, 15:40
Цитата Сообщение от Баир Посмотреть сообщение
да ну это же почти пример из книги
Книгу не вижу, потому какой там пример и о чем речь, представляю с трудом.
0
4 / 4 / 1
Регистрация: 20.02.2015
Сообщений: 24
15.10.2017, 22:33
Скажите, а в чем отличие в данном случае у Array и List. Почему в массиве мы можем спокойно менять поля структуры? Они по-разному хранят данные?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
15.10.2017, 23:23
Цитата Сообщение от Razor23Donetsk Посмотреть сообщение
в чем отличие в данном случае у Array и List.
Индексатор списка возвращает значение, а индексатор массива — переменную.
Следовательно, со структурами в массивах можно работать "напрямую", без лишнего копирования.

Цитата Сообщение от Razor23Donetsk Посмотреть сообщение
Они по-разному хранят данные?
Данные они хранят одинаково, просто индексаторы реализованы по-разному.
Массивы в шарпе — особый тип, со своими привилегиями.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.10.2017, 23:23
Помогаю со студенческими работами здесь

Ключевое слово constexpr: как определить удалось ли вычислить возвращаемое значение на этапе компиляции?
https://habrahabr.ru/post/228181/ Как определить удалось ли вычислить возвращаемое значение на этапе компиляции? Я понимаю что...

Изменить значение, возвращаемое ZoneId.systemDefault()
в тестах ZoneId.systemDefault() возвращает GMT, несмотря на то, что в @BeforeMethod стоит ...

Изменить возвращаемое значение в поле, чтобы считал процент при двух значений цен
Функция считает процент от изменения 2 цен и возвращает н/д в поле если 2 записи, если 3 и больше , то всё норм считает. Как исправить...

Ошипка в Uniti ошибка CS1612: невозможно изменить возвращаемое значение Transform.position, потому что это не переменна
using System.Collections; using System.Collections.Generic; using UnityEngine; public class pleyer : MonoBehaviour { ...

Как в List изменить значение с консоли
Здравствуйте! Как изменить значение точки с консоли? Вот мой код: { class Point3D { private int _x, _y; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

Новые блоги и статьи
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru