С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/40: Рейтинг темы: голосов - 40, средняя оценка - 4.78
1 / 1 / 0
Регистрация: 31.08.2014
Сообщений: 8
1

Указатель на ссылочный тип

31.08.2014, 15:32. Показов 8117. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток, не могу разобраться с маленькой проблемой:
Имеется класс "Car" (его внутреннее содержимое не важно), мне необходимо объявить указатель на объект этого
класса в программе (для того чтобы выполнять манипуляции с ним, неважно какие). Для этого, я в настройках
свойств проекта разрешил небезопасный код, затем в методе "Main" объявил переменную-объект этого класса. После
чего использовал ключевое слово "unsafe" для указания начала небезопасного кода, и внутри его тела объявил
ключевое слово "fixed" (так как без него по теории невозможно объявлять указатели на ссылочный тип, ибо
ссылочный тип располагается в куче и может быть удален или перемещен в памяти в любой момент). И вот тут
выявляется ошибка компиляции "Невозможно получить адрес или размер или объявить указатель для управляемого
типа ("Unsafes.Car")". Вот мой код:
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Unsafes
{
    class Car
    {
        public string name;
        public int age;
 
        public Car(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
 
        public override string ToString()
        {
            return string.Format("[name = {0}; age = {1}]", name, age);
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car("Suzuki Liana", 8);
 
            Console.WriteLine(myCar);
 
            unsafe
            {
                fixed (Car* myCarPointer = &myCar)    // тут ошибка
                {
                    // выполнить какие нибудь манипуляции..
                }
            }
            
            Console.ReadLine();
        }
    }
}
Немного поразмыслив, пришел к выводу, что myCar это ссылочный тип и в качестве его значения возвращается ссылка на адрес в памяти где находится объект. Поэтому решил что совсем не нужно выполнять операцию взятия адреса у объекта "myCar", так как его значение и есть адресс абъекта, а значит достаточно написать так:
C#
1
2
3
4
fixed (Car* myCarPointer = myCar)    // тут ошибка, ЗАМЕТЬТЕ отсутствие операции взятия адресса
    {
        // выполнить какие нибудь манипуляции..
    }
Это дало другую ошибку "Неявное преобразование типа "Unsafes.Car" в "Unsafes.Car*" невозможно", по которой видно что C# по умолчанию автоматически разыменовывает ссылочный тип (отличается от типа указателя), что говорит о том что первоначальный пример, по сути, написан правильно.

Незнаю как быть, может у вас есть идеи ?

В заранее спасибо..
0
IT_Exp
Эксперт
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
Блог
31.08.2014, 15:32
Ответы с готовыми решениями:

Ссылочный тип
Здравствуйте, сейчас интересуюсь теорией. Хочу посмотреть на выражение string field = null; чуть...

Тип string, ссылочный или примитивный?
Добрый день. До недавнего времени я считал тип "string" ссылочным. Сомнения в мой разум внесло...

Ссылочный тип, возвращать или задавать в методе
Вопрос может показаться странным, но как это обычно делают, допустим у меня есть объект класса...

Как же всё-таки сделать копию Liss<T>, где Т - ссылочный тип (в моем случае -- класс)
class T { int d; DateTime f; public T(int d, DateTIme date = new DateTime()) { d = d; f =...

7
870 / 720 / 304
Регистрация: 15.04.2013
Сообщений: 2,047
Записей в блоге: 5
31.08.2014, 16:09 2
Kurbanismailov,
Ваш способ сработает только для структур, для классов
C#
1
2
                TypedReference carRef = __makeref(myCar);            
                IntPtr ptr = **(IntPtr**)(&carRef);
0
1 / 1 / 0
Регистрация: 31.08.2014
Сообщений: 8
31.08.2014, 17:53  [ТС] 3
Спасибо за ответ, подскажите где почитать инфу про типы typedreference, intptr, а также метод __makeref.

Добавлено через 1 час 0 минут
Все, разобрался. Объясню для тех кому вдруг понадобится данная часть работы с языком C#.
1. Язык С# имеет 3 скрытых/недокументированных ключевых слова - __makeref, __reftype, __refvalue;
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
static void Main(string[] args)
{
    Car myCar = new Car("Suzuki Liana", 8);
 
    unsafe
    {
        // Теперь манипуляции выполняются сразу
 
        TypedReference trCar = __makered(myCar)    // __makeref принимает 1 параметр - объект, ссылку которого 
                                                                           // надо получить и возвращает объект TypedReference в котором
                                                                           // ссылка инкапсулирована.
 
        __refvalue(trCar, Car).name = "Ferrary"    // __refvalue принимает 2 параметра, 1-й есть ссылка 
                                                                      // (инкапсулированная в объект класса TypedReference) на объект в 
                                                                      // памяти, 2-й это тип согласно которому надо работать с       
                                                                      // инкапсулированной ссылкой. Возвращает объект того типа который 
                                                                      // указан во втором параметре.
 
        Type t = __reftype(trCar)    // __reftype принимает 1 параметр - объект типа TypedReference, Возвращает 
                                                 // реальный тип объекта находящегося в памяти по инкапсулированной в объект    
                                                 // TypedReference ссылке.
    }
 
    Console.WriteLine(myCar.name)    // Выведет строку "Ferrary".            
 
    Console.ReadLine();
}
Еще раз спасибо за наводку. Но все же у меня остался вопрос, неужели нельзя работать с указателями на классы также просто как это работает в С++ ?
1
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
31.08.2014, 18:05 4
дотнет задумывался специально чтоб "не работать с указателями", это не приветствуется
0
1 / 1 / 0
Регистрация: 31.08.2014
Сообщений: 8
31.08.2014, 18:09  [ТС] 5
Согласен, и это очень удобно, но бывают случаи, когда работа с указателями просто необходима, например: повышение производительности скорости работы приложения за счет оптимизации бизнес алгоритма. Там указатели могут хорошо помочь, если хорошо разбираться.
0
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
31.08.2014, 18:09 6
вот именно что это бессмысленно кроме очень редких исключений, как правило со структурами
вытаскивать указатели на классы это вообще дикость

из буханки хлеба с помощью нехитрых манипуляций можно сделать троллейбус
C#
1
2
 TypedReference trCar = __makered(myCar) ;
        __refvalue(trCar, Car).name = "Ferrary"
но зачем??
C#
1
myCar.name = "ferrary";
1
1 / 1 / 0
Регистрация: 31.08.2014
Сообщений: 8
31.08.2014, 18:19  [ТС] 7
Просто да, вот ты тоже)) изучаю возможности работы с памятью)
0
8 / 8 / 3
Регистрация: 20.05.2012
Сообщений: 174
15.02.2016, 15:55 8
Извиняюсь за некропостинг, только у меня почти тот же вопрос, что и у автора, только надо получить указатель в формате int.

Имеется внешняя функция, вида
C#
1
int ksGetObjParam(int @ref, object param, int parType)
Надо бы передать туда указатель объекта первым параметром.

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

Подскажите, пожалуйста, как получить значение указателя на ссылочный тип.
0
15.02.2016, 15:55
BasicMan
Эксперт
19315 / 2622 / 84
Регистрация: 17.02.2009
Сообщений: 10,364
Блог
15.02.2016, 15:55
Помогаю со студенческими работами здесь

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

Указатель на объект-тип
Здравствуйте, у меня не то чтобы вопрос, скорее прощу уточнить прав ли я. У любого ссылочного...

Ссылочный тип (тип указатель)
Такая проблема. Дали лабораторную работу на эту тему, однако как обычно ничего не объяснили....

Комбинированный тип. Ссылочный тип
1) Поле записи комбинированного типа представляет собой: а)описание переменной, в)описание простой...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Блоги программистов
Обновление сайта www.historian.b­y
Reglage 05.01.2025
Обещал подвести итоги 2024 года для сайта. Однако начну с того, что изменилось за неделю. Добавил краткий урок по последовательности действий при анализе вредоносных файлов и значительно улучшил урок. . .
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
Модель полного двоичного суматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list): s=^y] p=x and y for i in range(1,len(x)): s. append((x^y)^p) p=(x and y)or(p and (x or y)) return s x=list() y=list()
Это мы не проходили, это нам не задавали...(аси­­хронный счётчик с управляющим сигналом задержки).
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
Применение компонентов PrimeVue в Vue.js 3 на TypeScript
BasicMan 04.01.2025
Введение в PrimeVue и настройка окружения PrimeVue представляет собой мощную библиотеку компонентов пользовательского интерфейса для Vue. js 3, которая предоставляет разработчикам богатый набор. . .
Как стать Senior developer
cpp_developer 04.01.2025
В современной индустрии разработки программного обеспечения позиция Senior Developer представляет собой не просто следующую ступень карьерной лестницы, а качественно новый уровень профессионального. . .
Что известно о дате выхода Windows 12 и чего от нее ждать
IT_Exp 04.01.2025
В мире технологий постоянно происходят изменения, и операционные системы не являются исключением. Windows 11, выпущенная в октябре 2021 года, принесла множество инноваций и улучшений, но. . .
Что новенького в .NET Core 9
Programming 04.01.2025
Обзор ключевых изменений в . NET Core 9 Платформа . NET Core продолжает активно развиваться, и версия 9 представляет собой значительный шаг вперед в эволюции этой технологии. Новый релиз. . .
Инструкция по установке python3.13.1 в Debian 12
AlexSky-coder 03.01.2025
sudo apt update sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget. . .
Затестил триггеры. архив проекта прилагаю с GOA файлами в настройках архиватора проектов.
Hrethgir 03.01.2025
В этот раз нет закольцованности, потому что от неё только глюки, как я понял, логика не вырезанная. Триггеры очень быстрые если верить измерениям с помощью анализатора от Gowin. Есть ещё регистры,. . .
Python в помощь DevOps
IT_Exp 03.01.2025
Причины использования Python в работе DevOps Python стал неотъемлемой частью мира DevOps, и это не случайно. Этот язык программирования обладает множеством преимуществ, которые делают его. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru