Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
1

Не меняется поле структуры

01.03.2018, 08:06. Показов 1790. Ответов 20
Метки нет (Все метки)

Здравствуйте!
Подскажите, пожалуйста, почему не меняется поле во внутренней структуре:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
namespace ConsoleApplication1
{
    struct InternalSctuct
    {
        public String caption;
        public Int16 count;
        public Object obj;
        internal void Change(String newCaption)
        { caption = newCaption; }
 
        internal void Change(Int16 newCount)
        { count = newCount; }
        internal void Change(Object newObj)
        { obj = newObj; }
    }
    struct ExternalStruct
    {
        public InternalSctuct str;
        public ExternalStruct UpDate(dynamic newDate)
        { this.str.Change(newDate); return this; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            ExternalStruct str1 = new ExternalStruct();
            Console.WriteLine("Было caption: "+str1.str.caption);
            str1.UpDate("Вася"); 
            Console.WriteLine("Было caption: " + str1.str.caption);
            Console.ReadKey();
        }
    }
 
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.03.2018, 08:06
Ответы с готовыми решениями:

Копия структуры меняется при изменении оригинала
Есть структура. Хочу сделать ее резервную копию, создаю структуру такого же типа и присваиваю ей...

Функция внутри структуры использует указатель, как поле этой структуры
Коротко, есть класс A, описан в файле A_class.h ну и реализованы функции в A_class.cpp, есть файл...

Меняется формат даты в поле
Добрый день. Почему может меняться формат даты в поле веб-формы? Уже обновил версию...

Меняется только первая буква элемента структуры
В данной функции реализовано редактирование элементов структуры, там где int все заменяется...

20
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 08:31 2
Для такого вам классы нужны.
Структура каждый раз возвращается по значению. Вы хотите поменять поле, надо вызвать для него метод, тут структура копируется, вы меняете поле, структура может вернуться, опять же в копии, которую вы сразу потеряете.

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
 
namespace ConsoleAppGargonaMarkovna
{
    struct InternalStruct
    {
        public String caption;
        public Int16 count;
        public Object obj;
 
        internal InternalStruct Change(String newCaption)
        {
            this.caption = newCaption;
            return this;
        }
 
        internal InternalStruct Change(Int16 newCount)
        {
            this.count = newCount;
            return this;
        }
 
        internal InternalStruct Change(Object newObj)
        {
            this.obj = newObj;
            return this;
        }
    }
    struct ExternalStruct
    {
        public InternalStruct str;
 
        public ExternalStruct UpDate(dynamic newDate)
        {
            InternalStruct s = this.str.Change(newDate);
            return this;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            ExternalStruct str1 = new ExternalStruct();
            Console.WriteLine("Было caption: " + str1.str.caption);
            str1.UpDate("Вася");
            Console.WriteLine("Было caption: " + str1.str.caption);
            Console.ReadKey();
        }
    }
}
Миниатюры
Не меняется поле структуры  
1
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 08:56  [ТС] 3
Цитата Сообщение от Rius Посмотреть сообщение
Структура каждый раз возвращается по значению.
Я думала, что по значению она передаётся в качестве аргумента метода. А тут я вроде методы вызываю на данном экземпляре (this), который хочу изменить.
Цитата Сообщение от Rius Посмотреть сообщение
тут структура копируется, вы меняете поле, структура может вернуться
не пойму, где именно происходит возврат, который приводит к потере данных
0
669 / 215 / 88
Регистрация: 21.07.2016
Сообщений: 1,036
Записей в блоге: 2
01.03.2018, 10:17 4
Цитата Сообщение от GargonaMarkovna Посмотреть сообщение
C#
1
2
3
4
5
6
internal void Change(String newCaption)
* * * * { caption = newCaption; }
internal void Change(Int16 newCount)
* * * * { count = newCount; }
* * * * internal void Change(Object newObj)
* * * * { obj = newObj; }
можно заменить на Expression-bodied method
C#
1
2
3
4
5
internal void Change(String newCaption) => caption = newCaption;
 
internal void Change(Int16 newCount) => count = newCount;
 
internal void Change(Object newObj) => obj = newObj;
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 10:48 5
GargonaMarkovna, нет, здесь не то немного. Убираем dynamic и сразу работает.

Вот так с dynamic
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
 
namespace ConsoleAppGargonaMarkovna
{
    struct InternalSctuct
    {
        public String caption;
        internal void Change(String newCaption) { caption = newCaption; }
    }
 
    struct ExternalStruct
    {
        public InternalSctuct str;
        public ExternalStruct Update(dynamic newDate) { this.str.Change(newDate); return this; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            ExternalStruct str1 = new ExternalStruct();
            Console.WriteLine("Было caption: " + str1.str.caption);
            str1.Update("Вася");
            Console.WriteLine("Было caption: " + str1.str.caption);
            Console.ReadKey();
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ConsoleAppGargonaMarkovna.ExternalStruct
public ExternalStruct Update([Dynamic] dynamic newDate)
{
    if (ExternalStruct.<>o__1.<>p__0 == null)
    {
        ExternalStruct.<>o__1.<>p__0 = CallSite<Action<CallSite, InternalSctuct, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Change", null, typeof(ExternalStruct), new CSharpArgumentInfo[]
        {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
        }));
    }
    ExternalStruct.<>o__1.<>p__0.Target(ExternalStruct.<>o__1.<>p__0, this.str, newDate); // <<<<<<<<<<<<< Передача структуры в метод
    return this;
}

А так string:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
 
namespace ConsoleAppGargonaMarkovna
{
    struct InternalSctuct
    {
        public String caption;
        internal void Change(String newCaption) { caption = newCaption; }
    }
 
    struct ExternalStruct
    {
        public InternalSctuct str;
        public ExternalStruct Update(string newDate) { this.str.Change(newDate); return this; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            ExternalStruct str1 = new ExternalStruct();
            Console.WriteLine("Было caption: " + str1.str.caption);
            str1.Update("Вася");
            Console.WriteLine("Было caption: " + str1.str.caption);
            Console.ReadKey();
        }
    }
}
C#
1
2
3
4
5
6
// ConsoleAppGargonaMarkovna.ExternalStruct
public ExternalStruct Update(string newDate)
{
    this.str.Change(newDate);
    return this;
}


Не пишите так.

Добавлено через 1 минуту
Избегайте dynamic кроме случаев, для которых он задуман:
Тип dynamic включает операции, в которых он применяется для обхода проверки типов во время компиляции. Такие операции разрешаются во время выполнения. Тип dynamic упрощает доступ к API COM, таким как API автоматизации Office, а также к динамическим API, таким как библиотеки IronPython, и к HTML-модели DOM.
И избегайте структур, где они не нужны.
Вот так (выглядят) пишутся методы для модификации структур: https://msdn.microsoft.com/en-... etime.aspx
1
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 10:54  [ТС] 6
результат не поменялся

Добавлено через 3 минуты
dailydose,
от использования => результат не изменился
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 10:54 7
Не меняется поле структуры
0
dailydose
01.03.2018, 10:56
  #8

Не по теме:

Цитата Сообщение от GargonaMarkovna Посмотреть сообщение
результат не поменялся
это не влияет на результат, просто для удобства:)

0
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 14:02  [ТС] 9
Rius,
поясните, пожалуйста, этот код
// ConsoleAppGargonaMarkovna.ExternalStruct
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public ExternalStruct Update([Dynamic] dynamic newDate)
{
    if (ExternalStruct.<>o__1.<>p__0 == null)
    {
        ExternalStruct.<>o__1.<>p__0 = CallSite<Action<CallSite, InternalSctuct, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Change", null, typeof(ExternalStruct), new CSharpArgumentInfo[]
        {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
        }));
    }
    ExternalStruct.<>o__1.<>p__0.Target(ExternalStruct.<>o__1.<>p__0, this.str, newDate); // <<<<<<<<<<<<< Передача структуры в метод
    return this;
}
Это как внутренне переводится dynamic в нужный тип?
В 11ой строке this.str - это и есть передача по значению?
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 14:18 10
Цитата Сообщение от GargonaMarkovna Посмотреть сообщение
Это как внутренне переводится dynamic в нужный тип?
Это то, во что компилируется типа простой и понятный метод
C#
1
public ExternalStruct Update(dynamic newDate) { this.str.Change(newDate); return this; }
, как показывает ILSpy.
Цитата Сообщение от GargonaMarkovna Посмотреть сообщение
В 11ой строке this.str - это и есть передача по значению?
Да.
0
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 14:20  [ТС] 11
Цитата Сообщение от Rius Посмотреть сообщение
как показывает ILSpy
А это кто?
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 14:23 12
ILSpy — open source альтернатива .NET Reflector
1
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 14:27  [ТС] 13
Цитата Сообщение от Rius Посмотреть сообщение
И избегайте структур, где они не нужны.
Вот так (выглядят) пишутся методы для модификации структур: https://msdn.microsoft.com/en-... etime.aspx
А можно эту мысль поподробнее пояснить?
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 15:57 14
DateTime - структура. Её методы не модифицируют её экземпляр, а возвращают новый.
0
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 18:42  [ТС] 15
Цитата Сообщение от Rius Посмотреть сообщение
методы не модифицируют её экземпляр, а возвращают новый.
А зачем так делается? Неужели это проще (создать новый экземпляр, часть данных в который надо занести из уже имеющейся структуры, а часть из параметра метода), чем изменить поля уже существующей?
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
01.03.2018, 18:56 16
Да, удобнее. Структура это value type и она копируется по значению.
Когда вы получаете доступ к такой структуре из списка, словаря или из свойства, то вы уже получаете её копию. Применение такого способа доступа, как вы пытаетесь, в этом случае просто бы не работало. Так что создание таких методов вводит в заблуждение и не применимо.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
 
namespace ConsoleAppGargonaMarkovna
{
    struct DataItem
    {
        public int Value;
        public void Set(int value) { this.Value = value; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            List<DataItem> items = new List<DataItem>();
            items.Add(new DataItem() { Value = 1 });
            items[0].Set(2);
 
            // Выводится 1, а не 2
            foreach (var item in items)
            {
                Console.WriteLine(item.Value);
            }
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
 
namespace ConsoleAppGargonaMarkovna
{
    struct DataItem
    {
        public int Value;
        public void Set(int value) { this.Value = value; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, DataItem> map = new Dictionary<string, DataItem>();
            map.Add("1", new DataItem() { Value = 1 });
            map["1"].Set(2);
 
            // Выводится 1, а не 2
            foreach (var pair in map)
            {
                Console.WriteLine(pair.Value.Value);
            }
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
 
namespace ConsoleAppGargonaMarkovna
{
    struct DataItem
    {
        public int Value;
        public void Set(int value) { this.Value = value; }
    }
 
    class Data
    {
        public DataItem Item { get; set; }
 
        public Data()
        {
            this.Item = new DataItem() { Value = 0 };
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Data a = new Data();
            a.Item.Set(1);
 
            // Выводится 0, а не 1
            Console.WriteLine(a.Item.Value);
        }
    }
}
1
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
01.03.2018, 23:04  [ТС] 17
Наверно, дело в том, что все методы относятся к объекту, и при вызове метода на экземпляре происходит передача адресов полей экземпляра ( а в случае структуры - копии данных, что при использовании this. для меня не было очевидным), т.е. методы в структуре для изменения полей экземпляров - бессмысленная вещь.
Rius, большое СПАСИБО!
0
Эксперт .NET
7701 / 5165 / 1233
Регистрация: 25.05.2015
Сообщений: 15,727
Записей в блоге: 14
02.03.2018, 06:11 18
Нет, сами методы работают:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
 
namespace ConsoleAppGargonaMarkovna
{
    public struct InternalSctuct
    {
        public String caption;
        public void Change(String newCaption) { this.caption = newCaption; }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            InternalSctuct a = new InternalSctuct();
            a.caption = "1";
            Console.WriteLine("Было caption: " + a.caption);
            a.Change("2");
            Console.WriteLine("Стало caption: " + a.caption);
            Console.ReadKey();
        }
    }
}
Но из-за value type можно не заметить и накосячить в коде.
1
0 / 0 / 0
Регистрация: 23.12.2017
Сообщений: 43
02.03.2018, 09:02  [ТС] 19
В коде в посте #16 при использовании индексаторов и свойств, которые являются методами и происходит передача по значению, и они изменяют данные копии; так и при использовании dynamic получается.
0
669 / 215 / 88
Регистрация: 21.07.2016
Сообщений: 1,036
Записей в блоге: 2
04.03.2018, 20:43 20
Цитата Сообщение от GargonaMarkovna Посмотреть сообщение
методы в структуре для изменения полей экземпляров - бессмысленная вещь.
Почему так? Я что-то не понял)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2018, 20:43

Не меняется значение если курсор в поле
$('').blur(); $('').attr('value', '2'); Значение атрибута меняется, но меняется значение в...

Почему в поле INT меняется значение ?
В базе есть поле INT(12). В него планировалось вводить ИНН. При вводе в input значения...

Формула в поле формы меняется от условий
Добрый день. Подскажите, пожалуйста, как реализовать в форме вычисляемое поле, записанное в...

Передача массива в поле структуры
Необходимо передать массив из 3 значений передать в аналогичное поле в структуре. При попытке...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.