| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Предаване на параметър на метод по стойност в C# http://mcu-bg.com/mcu_site/viewtopic.php?f=14&t=18050 |
Страница 1 от 1 |
| Автор: | ¶ [ Пет Окт 15, 2021 6:07 pm ] | ||||||||||||||||||||||||||||||||||||
| Заглавие: | Предаване на параметър на метод по стойност в C# | ||||||||||||||||||||||||||||||||||||
C# по подразбиране предава параметрите на методите по адрес (reference), изключения са базовите типове данни (int, double, string и т.н.), както и прости структури (които нямат масиви например). Имам следната C# структура:
Тази структура ще се добавя от работна нишка в стандартна System.Collections.Generic.Queue, след което сигнализира главната нишка за последваща обработка. Направих нещо съвсем просто: заделих памет за TPCANMsg в работната нишка и всеки път когато дойдат данни ги копирам в нейните полета, след което викам Queue.Enqueue(msg). Понеже DATA[] е масив, C# го предава на Enqueue() като адрес и съответно в опашката всички предходни елементи се променят, което не искам да бъде така. Целият код е по-долу:
Резултата от кода:
Както се вижда от резултата C# е подал DATA[] масива като адрес, затова изваждайки двата елемента имам еднакви DATA[], докато ID е наред. Най-тъпото което се сетих е да променя структурата така:
След което при Enqueue() и Dequeue() с опашката всичко е наред, понеже този път в структурата няма масив и C# я предава като параметър по стойност. Не ми се ще обаче да имам такава междинна структура, искам да е оригиналната с масив в нея. Има ли начин на C# да се укаже да предаде структура/клас като параметър на метод по стойност ? Ако няма, как постъпвате когато трябва да предадете по стойност ? |
|||||||||||||||||||||||||||||||||||||
| Автор: | slav4o.com [ Пет Окт 15, 2021 7:43 pm ] |
| Заглавие: | Re: Предаване на параметър на метод по стойност в C# |
Ами видимо имаш само един физически създаден масив msg.DATA = new byte[8]; при Dequeue() пак дърпаш "неговата инстанция", фактически нашиваш данните два пъти на едно място и при Dequeue() дърпаш последните данни. .... Според мен трябва на второто зареждане на данни за тест, да напишеш още веднъж msg.DATA = new byte[8]; и да инициализираш новите данни. Така ще имаш 2 физически масива в паметта които да държат данните. edit: Ако данните за масива идват от масив, може да използваш Array.Copy да не ги зареждаш с цикъл елемент по елемент. То този метод сигурно така работи де... |
|
| Автор: | palavrov [ Нед Окт 17, 2021 6:36 pm ] |
| Заглавие: | Re: Предаване на параметър на метод по стойност в C# |
Трябва да си направиш shallow или deep clone на обекта - пусни едни гугле и ще намериш достатъчно страници как да подкараш всичко. |
|
| Автор: | ¶ [ Пон Окт 18, 2021 4:32 pm ] | |||||||||||||||||||||||||||||||||||||||||||||
| Заглавие: | Re: Предаване на параметър на метод по стойност в C# | |||||||||||||||||||||||||||||||||||||||||||||
Благодаря за отговорите. Всъщност бях разбрал, че му липсва
но по скоро ме интересуваше някакъв друг начин. Ще видя тези shallow и deep clone, но видях че C# предлага и още един начин, fixed:
но при компилиране дава грешка:
Добавям unsafe към дефиницията на структурата:
и сега се оплаква, че:
Та сега въпроса ми е: fixed и unsafe за структурата, компилирам проекта като unsafe и работи под Windows, но това unsafe/fixed дали няма да създаде подводни камъни при билдване на други платформи ? C# е малко като манджа с грозде |
||||||||||||||||||||||||||||||||||||||||||||||
| Автор: | slav4o.com [ Пон Окт 18, 2021 8:51 pm ] |
| Заглавие: | Re: Предаване на параметър на метод по стойност в C# |
Ами когато включиш unsafe опцията вече може и така да стане Доколкото виждам struct във C# еквивалентно на typedef struct във C/C++. T.e. това не е обект а сложен тип. Т.е. трябва да напишеш нещо от сорта на myStruct CANMsg; naBaiIvanStructurata CANMsg; Всъщност защо не използваш само класове ? Принципно всеки метод получава аргументите по стойност. Референтните типове са пак стойност която държи тип и адрес на обекта към който сочат. За да може реално Dequeue() да извлече данните обекта който се подава на Queue() трябва да съществува в паметта във момента на Dequeue() така той реално ще съхранява физически въпросният масив, а в опашката ще имаш референция към него. Ако обектът който се подава на Queue() е Dispose()-нат към момента на Dequeue() естествено трябва да си правиш локални копия в твоите обекти от опашката. |
|
| Автор: | ¶ [ Вто Окт 19, 2021 2:03 pm ] |
| Заглавие: | Re: Предаване на параметър на метод по стойност в C# |
Не ползвам само класове, защото чета от C++ DLL, и там данните са struct. |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|