Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Массив в составе структуры


Автор: opozdaika 28.7.2008, 12:05
Я конечно глубоко зивиняюсь, что вновь поиднимаю это тему, но не доходит до меня. Все-таки можно или нет определить структуру, в которой есть массив постоянного размера? Я знаю, что классы располагаются в куче, а структуры - в стеке. И я знаю, что структуры передаются по значению, а классы по ссылке. И понимаю, что в связи с этим размер структуры должен быть мааааааленьким. НО все равно мне нужно это! У меня массивчик малюсенький, но для удобства он должен быть внутри структуры! 
Ниже результат моих поисков. Вариант с new  не очень меня привлекает, т.к. такой малюсенький массивчик лучше хранить физически в самой структуре.  Кстати, вариант с разбиением массива на N отдельных скалярных полей - оффтоп.
Код

        public struct MyStruct
        {
            public int MyArray[2];
        }
// CS0650: Bad array declarator: To declare a managed array the rank specifier precedes the variable's identifier. 
//   To declare a fixed size buffer field, use the fixed keyword before the field type.

        public struct MyStruct
        {
            public int[2] MyArray;
        }
// CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)

        public struct MyStruct
        {
            public int[] MyArray = new int[2];
        }
// CS0573: MyStruct.MyArray: cannot have instance field initializers in structs

        public struct MyStruct
        {
            public fixed int MyArray[2];
        }
// CS0214: Pointers and fixed size buffers may only be used in an unsafe context

        unsafe public struct MyStruct
        {
            public fixed int MyArray[2];
        }
// CS0227: Unsafe code may only appear if compiling with /unsafe


Автор: PashaPash 28.7.2008, 13:53
opozdaika, для какого удобства?
Частью структуры можно сделать fixed size buffer, если структура unsafe. Чтобы откомпилировалось без CS0227, нужно поставить галочку Allow Unsafe Code на закладке Build в свойствах проекта.

Автор: Robust 28.7.2008, 18:34
Попробуй добавить конструктор в котором инициализируются все поля структуры
Вроде такого:
Код

        public struct MyStruct
        {
            public int[2] MyArray;
            
            public MyStruct(int[] MyArray)
            {
                     this.MyArray = MyArray;
            }
        }

Автор: PashaPash 29.7.2008, 11:49
Цитата(Robust @  28.7.2008,  18:34 Найти цитируемый пост)
Попробуй добавить конструктор в котором инициализируются все поля структуры
И после этого массив будет хранится в стеке, как часть структуры?

Автор: Robust 30.7.2008, 02:16
Цитата

И после этого массив будет хранится в стеке, как часть структуры?


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

А чтобы выделять массив стеке нужно использовать unsafe код.

Например так:
Код

    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                MyStruct ms; // Выделяем в стеке память для массива

                Int32 width = 5;

                for (int i = 0; i < width; i++)
                {
                    ms.MyArray[i] = i;
                }

                for (int i = 0; i < width; i++)
                {
                    Console.WriteLine(ms.MyArray[i]);
                }

                Console.ReadLine();
            }
        }
    }

    public unsafe struct MyStruct
    {
        public fixed int MyArray[5];
    }


И не забудь поставить флажок в свойстве проекта "Allow unsafe code"

Автор: opozdaika 30.7.2008, 14:01
Robust,  да все правильно. Так у меня работает. Но мне не понравилось, что нужно везде, где работаешь со структурой, писать unsafe. Да еще и эта галочка подозрительная... Поэтому я отказался от использования struct в пользу class. Наверное, лучше забыть о том, что в C# есть структуры. 

Автор: PashaPash 30.7.2008, 17:28
Цитата(Robust @  30.7.2008,  02:16 Найти цитируемый пост)
Нет. Массив - это ссылочный тип. В структуре будет храниться ссылка на массив, который будет создаваться в куче, со всеми вытекающими последствиями.
А чтобы выделять массив стеке нужно использовать unsafe код.

Это и написано в  первом посте топика. При чем тут вообще конструктор и инициализация полей?
Цитата(Robust @  30.7.2008,  02:16 Найти цитируемый пост)
И не забудь поставить флажок в свойстве проекта "Allow unsafe code" 

А это во втором посте топика.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)