Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Значимые и ссылочные типы данных 
:(
    Опции темы
Idsa
Дата 23.1.2007, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Тип int  - значимый тип данных, соответственно и переменные этого типа хранятся в стеке. Меня интересует, каким типом (значимым или ссылочным) является интовый массив, ну и соответственно, где будет хранитсья объект int[] a (в куче или стеке):
int a - значимый
int[] a - ?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Дрон
Дата 23.1.2007, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Ссылочный, а следовательно:

1) память под элементы массива выделяется в куче, а не на стеке
2) ему можно присвоить значение null  ( int[] a = null; )

ну и к тому же все массивы, являются производными от класса System.Array, хотя и неявно.

Это сообщение отредактировал(а) Дрон - 23.1.2007, 23:48


--------------------
Да. Именно так.
PM   Вверх
Idsa
Дата 24.1.2007, 04:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Дрон, спасибо.
Это что-то меня ночью вдруг очень заинтересовал этот вопрос, а утром проснулся и понял, что ответ-то очевиденsmile Не зря говорят утро вечера мудренее...smile

Добавлено @ 04:34 
А кстати, корректно ли переводить value type как значимый? А то вон в Троелсене-то вообще переводится "типы, характеризуемые значениями".


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Дрон
Дата 24.1.2007, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 24
Всего: 93



Цитата(Idsa @  24.1.2007,  04:25 Найти цитируемый пост)
А кстати, корректно ли переводить value type как значимый

Вообще слух немного режет, но как правильней -- не знаю. Надо в МСДН на русском поискать.


--------------------
Да. Именно так.
PM   Вверх
Idsa
Дата 24.1.2007, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



В русском MSDN'e используется термин "типы значений". Тоже не очень красиво smile


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
ivashkanet
Дата 24.1.2007, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(Idsa @  24.1.2007,  12:58 Найти цитируемый пост)
В русском MSDN'e используется термин "типы значений". Тоже не очень красиво

А какая разница? Тут не капитан Врунгель "Как вы лодку назовете, так она и поплывет" smile

Тут, как не назови --- будет работать smile


P.S. Я называю ссылочные и значимые типы smile
PM MAIL WWW ICQ   Вверх
anonym
Дата 24.1.2007, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 27.11.2006

Репутация: 3
Всего: 3



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

struct MyType
{
    public int[,] Data;
    public int x;
}

то в стеке хранится значение х, а так же адрес первого элемента массива, хранящегося в куче?
PM MAIL   Вверх
ivashkanet
Дата 24.1.2007, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(anonym @  24.1.2007,  13:27 Найти цитируемый пост)
то в стеке хранится значение х, а так же адрес первого элемента массива, хранящегося в куче?

Ага, только вот не уверен насчет "адреса первого элемента". 
Мало ли как они там хранят эти данные smile 
Это не рассказывается 
PM MAIL WWW ICQ   Вверх
Idsa
Дата 24.1.2007, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(ivashkanet @  24.1.2007,  14:23 Найти цитируемый пост)
P.S. Я называю ссылочные и значимые типы 

Нас как минимум двое smile

Цитата(ivashkanet @  24.1.2007,  14:34 Найти цитируемый пост)
Ага, только вот не уверен насчет "адреса первого элемента". Мало ли как они там хранят эти данные 

Ну а как иначе-то? Думаю, anonym прав.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
ivashkanet
Дата 24.1.2007, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(Idsa @  24.1.2007,  14:13 Найти цитируемый пост)
Ну а как иначе-то?

Как-нибудь smile
Цитата(Idsa @  24.1.2007,  14:13 Найти цитируемый пост)
Думаю, anonym прав.

Я тоже так думаю, но утверждать не берусь 
PM MAIL WWW ICQ   Вверх
anonym
Дата 29.1.2007, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 27.11.2006

Репутация: 3
Всего: 3



Что-то я не въехал в одну вещь. Прочитал в Троелсене
В главе 2 рассказывалось о том, что в классе System.Object определен метод МеmberwiseClone(). Этот метод используется для специального типа копирования объекта — когда реальное копирование не происходит, а вместо этого создается еще одна ссылка на область оперативной памяти, занимаемую данным объектом. Для такого типа копирования используется специальный термин — «поверхностное копирование» (shallow сору). Пользователи объектов не вызывают метод MemberwiseClone() напрямую — он вызывается автоматически, когда к объектам ссылочного типа применяется оператор назначения (=), то есть одна ссылка начинает указывать на ту же область оперативной памяти, что и другая.
Пример из msdn-a.
Код

using System;

class MyBaseClass
{
    public static string CompanyName = "My Company";
    public int age;
    public string name;
}

class MyDerivedClass : MyBaseClass
{
    static void Main()
    {
        MyDerivedClass m1 = new MyDerivedClass();
        m1.age = 42;
        m1.name = "Sam";
        
        MyDerivedClass m2 = (MyDerivedClass)m1.MemberwiseClone();
        m1.age = 50;
        
        MyDerivedClass m3 = new MyDerivedClass();
        m3.age = 42;
        m3.name = "Sam";
        
        MyDerivedClass m4 = m3;
        m3.age = 50;
        
        Console.WriteLine(m2.age);
        Console.WriteLine(m4.age);
    }
}

Тогда, если при выполнении оператора = вызывается данный метод, должны вывестись одинаковые строки. Но выводит 42 и 50. Почему так?
PM MAIL   Вверх
mr.DUDA
Дата 29.1.2007, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(anonym @  24.1.2007,  13:27 Найти цитируемый пост)
А такой вопрос. Структура по идее хранится в стеке. А что если одно из полей структуры будет к примеру массив? Правильно ли я понимаю, что если у нас есть структура

Цитата(anonym @  24.1.2007,  13:27 Найти цитируемый пост)
то в стеке хранится значение х, а так же адрес первого элемента массива, хранящегося в куче?

Если есть структура, поле которой - ссылочный тип, то в структуре будет некий адрес, не обязательно совпадающий с адресом первого элемента массива. Первый элемент можно получить из Marshal.UnsafeAddrOfPinnedArrayElement.

Цитата(anonym @  29.1.2007,  22:34 Найти цитируемый пост)
Тогда, если при выполнении оператора = вызывается данный метод, должны вывестись одинаковые строки. Но выводит 42 и 50. Почему так?

Глядя на пример, всё правильно выводит.


--------------------
user posted image
PM MAIL WWW   Вверх
anonym
Дата 30.1.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 27.11.2006

Репутация: 3
Всего: 3



Цитата(mr.DUDA @  29.1.2007,  23:45 Найти цитируемый пост)
Глядя на пример, всё правильно выводит. 

Так если у нас m1 и m2 ссылаются на одну область оперативной памяти, когда меняем m1.age на 50, m2.age тоже должно изменится на 50... Короче так же, как и в простом присваивании m4 = m3... Что я неправильно понимаю?...  smile 

Это сообщение отредактировал(а) anonym - 30.1.2007, 09:44
PM MAIL   Вверх
ivashkanet
Дата 30.1.2007, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(anonym @  29.1.2007,  22:34 Найти цитируемый пост)
МеmberwiseClone(). Этот метод используется для специального типа копирования объекта — когда реальное копирование не происходит, а вместо этого создается еще одна ссылка на область оперативной памяти, занимаемую данным объектом. Для такого типа копирования используется специальный термин — «поверхностное копирование» (shallow сору).

Не знаю где ты такое взял, но по моим сведениям МеmberwiseClone() делает копию объекта, но не глубокую (shalllow). Т.е. если у объекта есть поля-ссылки, то там будет только копия ссылки. В отличии от Deep Copy когда создается полная копия дерева объекта.
Цитата(MSDN)

Remarks
The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.

For example, consider an object called X that references objects A and B. Object B, in turn, references object C. A shallow copy of X creates new object X2 that also references objects A and B. In contrast, a deep copy of X creates a new object X2 that references the new objects A2 and B2, which are copies of A and B. B2, in turn, references the new object C2, which is a copy C. Use a class that implements the ICloneable interface to perform a deep or shallow copy of an object. 


Пример:
Код

        [STAThread]
        static void Main(string[] args)
        {
            MyClass o1 = new MyClass();
            MyClass o2 = o1.GetShallowCopy(o1);

            if (o1.Equals(o2))
            {
                Console.WriteLine("Ссылки на объекты совпадают");
            }
            else
            {
                Console.WriteLine("Ссылки на объекты не совпадают");
            }
            Console.ReadKey();
        }
        class MyClass
        {
            public static string CompanyName = "My Company";
            public int age;
            public string name;
            public MyClass GetShallowCopy(MyClass o)
            {
                return (MyClass)o.MemberwiseClone();
            }
        }

PM MAIL WWW ICQ   Вверх
anonym
Дата 30.1.2007, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 27.11.2006

Репутация: 3
Всего: 3



Цитата(ivashkanet @  30.1.2007,  10:32 Найти цитируемый пост)
Не знаю где ты такое взял

Троелсен жжёт...
Троелсен. Э. С# и платформа .NET. Библиотека программиста. — СПб.: Питер, 2004. —796 с. ISBN 5-318-00750-3 страница 212  smile 

Короче, из вышесказанного, как я понял, следует, что метод MemberwiseClone() и знак = равноправны только в том случае, если все поля объекта - ссылочные. Правильно я понял?

PM MAIL   Вверх
ivashkanet
Дата 30.1.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(anonym @  30.1.2007,  10:18 Найти цитируемый пост)
Правильно я понял?

Нет. Только для структурных типов (там по равенству создается новый экземпляр).
А для ссылочных "=" --- коприование ссылки на объект
PM MAIL WWW ICQ   Вверх
anonym
Дата 30.1.2007, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 27.11.2006

Репутация: 3
Всего: 3



Я имею ввиду, если мы создали объект какого-то класса, затем присвоили этот объект другому, то при изменении любых полей одного объекта будет меняться и второй. Верно? И если применить метод MemberwiseClone(), то для класса, где все поля ссылочные - скопируются все ссылки (т. е. как при = ), а если есть значимые типы, то для них будет скопировано само значение.
PM MAIL   Вверх
EvgenZ
Дата 28.2.2007, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: нет
Всего: 11



Всем привет, такой вопрос, как я понял Clone() это метод интерфейса ICloneable, и класс у которого собираюсь сделать Clone()  должен наследовать интерфейс ICloneable, но почему привпеденный код работает без наследования? Это правильно или это правильно только для данного примера и в нормальном проекте потерпит фиаско, или даже здесь это неправильно.
Код

using System;

namespace name 
{
    class two 
    {
        public int getmC 
        {
            get { return mC; }
            set { mC = value; }
        }
        private int mC;        
    };
    

    class one 
    {
        two t = new two();
        public int getmI
        {
            get{return mI;}
            set { mI = value; }            
        }
        public int getmJ 
        {
            get { return mJ; }
            set { mJ = value; }
        }

        public two getC 
        {
            get { return t; }
        }

        public object Clone()
        {
            return new one();
        }

        private int mI, mJ;
    };

    class main     
    {
        public static void Main() 
        {
            one o = new one();
            one o1 = (one)o.Clone();

            o.getC.getmC = 33;
            o.getmJ = 5;
            o.getmI = 7;
            o1.getmI = 111;
            o1.getmJ = 999;
            Console.WriteLine("mI= {0}  mJ= {1}, mI1= {2}  mJ1= {3},   mC= {4}, mC1= {5}", o.getmI, o.getmJ, o1.getmI,
                o1.getmJ, o.getC.getmC, o1.getC.getmC );                        
        }
    }


}



--------------------
<удалено администрацией форума>
PM MAIL   Вверх
ivashkanet
Дата 28.2.2007, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



EvgenZ, а в чем проблема? Метод Clone можно вызвать только потому, что он есть  smile 

Интерфейсы нужны для того, чтобы классы, которые ничего не знают о классе кроме того, что он реализует (это слово более точно, чем "наследует") конкретный интерфейс, все же могли вызывать методы объявленные в интерфейсе.

Откуда, например, MS могло знать о классе "class one". Что не помешало ему создать кучу методов, в которых используется метод Clone() и интерфейса IClonable. 
Вроде часть технологии ремоутинг очень сильно юзает его
PM MAIL WWW ICQ   Вверх
Idsa
Дата 28.2.2007, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Чтобы обеспечить классу возможность вовращать свою копию, можно реализовать интерфейс ICloneable, которые содержит единственный метод - Clone():
Код

public interface ICloneable
  {
    // Summary:
    //     Creates a new object that is a copy of the current instance.
    //
    // Returns:
    //     A new object that is a copy of this instance.
    object Clone();
  }

Если наш класс не содержит ссылочных типов данных, то реализация клонирования предельно проста:
Код

public object Clone()
{
  return this.MemberwiseClone();
}

Если же в классе есть ссылочные типы данных, то метод MemberwiseClone() вернет их поверхностные копии (тупо скопирует ссылки на те же объекты). В этом случае клонирование нужно выполнять ручками.
Реализуем клонирование для твоего класса one. Чтобы облегчить себе жизнь, сначала вызовем MemberwiseClone(), а затем изменим значение для нашего единственного ссылочного типа данных - объекта класса two. 
Код

public object Clone()
{
  one tmp = (one)this.MemberwiseClone();
  two tmp2 = new two();
  tmp2.getmC = this.t.getmC();
  tmp.t = tmp2;
  return tmp;
}



--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
EvgenZ
Дата 28.2.2007, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: нет
Всего: 11



Т.е. можно не писать 
Код

class one : ICloneable


а просто в класе описать интерфейс?



И что-то не работает ))) подскажите пожалуйста
Код

using System;

namespace name 
{
    class two 
    {
        public int getmC 
        {
            get { return mC; }
            set { mC = value; }
        }
        private int mC;        
    };
    

    class one 
    {
        two t = new two();
        public int getmI
        {
            get{return mI;}
            set { mI = value; }            
        }
        public int getmJ 
        {
            get { return mJ; }
            set { mJ = value; }
        }

        public two getC 
        {
            get { return t; }
            set { t = value; }
        }

        public object Clone()
        {
            one q = (one)this.MemberwiseClone();
            two t = new two();
            t.getmC = this.getC.getmC;
            q.getmI = this.getmI;
            q.getmJ = this.getmJ;
            return q;
        }

        private int mI, mJ;
    };

    class main     
    {
        public static void Main() 
        {
            one o = new one();
            one o1 = (one)o.Clone();

            o.getC.getmC = 33;
            o1.getC.getmC = 44;
            o.getmJ = 5;
            o.getmI = 7;
            o1.getmI = 111;
            o1.getmJ = 999;
            Console.WriteLine("mI= {0}  mJ= {1}, mI1= {2}  mJ1= {3},   mC= {4}, mC1= {5}", o.getmI, o.getmJ, o1.getmI,
                o1.getmJ, o.getC.getmC, o1.getC.getmC );                        
        }
    }


}


Это сообщение отредактировал(а) EvgenZ - 28.2.2007, 22:52


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Idsa
Дата 28.2.2007, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Конечно, можно! Но не нужно smile. Реализация интерфейся придает классу дополнительную функциональность. Реализовав интерфейс, мы можем сделать, например вот так:
Код

      one t = new one();
      if (t is ICloneable)
        t.Clone();
      else
        Console.WriteLine("Извините, копирование объекта невозможно!");

Приведенный код позволяет проверить, реализован ли у класса определенный интерфейс.
Подобный подход может быть полезен, например, когда хранишь массив ссылок на различные объекты, используя интерфейсный полиморфизм. Дык вот в этом массиве некоторые объекты могут поддерживать интерфейс, а другие - нет. Если бы мы не реализовали интерфейс, такую проверку сделать было бы нельзя.


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
EvgenZ
Дата 28.2.2007, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: нет
Всего: 11



Respect! подскажите еще пожалуйста, что не так в последнем примере, почему ссылочное поле  "t" продолжает указывать в одно место?


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Idsa
Дата 28.2.2007, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(EvgenZ @  28.2.2007,  22:45 Найти цитируемый пост)
И что-то не работает ))) подскажите пожалуйста

Во-первых, строчки
Код

q.getmI = this.getmI;
q.getmJ = this.getmJ;

нужно удалить: за нас это сделает Memberwise.Clone().
А поверхностное копирование выполняется из-за того, что не присваивается
Код

q.t = t;

Добавим эту строчку, удалим 2 вышеописанные и в итоге получим:
Код

    public object Clone()
    {
      one q = (one)this.MemberwiseClone();
      two t = new two();
      t.getmC = this.getC.getmC;
      q.t = t;
      return q;
    }



--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
EvgenZ
Дата 1.3.2007, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: нет
Всего: 11



немогу никак понять,  q.t = t; почему = t, что такое t - это локальная переменная почему просто t ... может утро вечера мудренее ))

Добавлено @ 00:26 
и если я явно пишу копирование полей не ссылочных, это разве плохо?


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Idsa
Дата 1.3.2007, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(EvgenZ @  1.3.2007,  00:24 Найти цитируемый пост)
может утро вечера мудренее ))

Зачем откладывать на утро то, что можно сделать ночью? smile

Сейчас еще раз посмотрел на код и задумался: "А почему он работает?" smile t у нас private, а мы к нему напрямую обращаемся в Clone()... но при этом все работает! Я в шоке.

Правильно, конечно, будет заменить строчку q.t = t на q.getC = t;

Добавлено @ 00:48 
Цитата(EvgenZ @  1.3.2007,  00:24 Найти цитируемый пост)
и если я явно пишу копирование полей не ссылочных, это разве плохо?

Это не плохо. Вполне нормально. Только при этом не нужно вызывать MemberwiseClone(), т. к. это бессмысленно.

Добавлено @ 00:58 
Цитата(Idsa @  1.3.2007,  00:43 Найти цитируемый пост)
Сейчас еще раз посмотрел на код и задумался: "А почему он работает?"  t у нас private, а мы к нему напрямую обращаемся в Clone()... но при этом все работает! Я в шоке.

Пытаюсь разобраться... При клонировании мы в классе one создаем объект o типа one. При этом нам доступны private-члены этого объекта... Может, это такая фишка, чтобы упростить клонирование?

Это сообщение отредактировал(а) Idsa - 1.3.2007, 01:13


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
EvgenZ
Дата 1.3.2007, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: нет
Всего: 11



А t разве не локальная переменная?  smile 

Код

public object Clone()
        {
            one q = (one)this.MemberwiseClone();
            two tt = new two();
            tt.getmC = this.getC.getmC;
            q.t = tt; 
            return q;
        }


ихихих кажется понял, сам себя запутал, зато длагодаря этому вроде понял, как это работает!

Это сообщение отредактировал(а) EvgenZ - 1.3.2007, 11:24


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Naum
Дата 1.3.2007, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

Репутация: 8
Всего: 15



Цитата(Idsa @  1.3.2007,  01:43 Найти цитируемый пост)
t у нас private, а мы к нему напрямую обращаемся в Clone()... но при этом все работает! Я в шоке.

Если в классе C объявлен приватный член M. То у любых экземпляров класса C, созданных в методах класса C, член M будет видимым.
Грубо говоря, если человек знает свое строение, то он знает строение любого другого человека. Однако он не знает строение, например, собаки, пока не разрежет ее, или по нашему не взломает. ))


--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
Idsa
Дата 1.3.2007, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(Naum @  1.3.2007,  11:36 Найти цитируемый пост)
Если в классе C объявлен приватный член M. То у любых экземпляров класса C, созданных в методах класса C, член M будет видимым.

Naum, +1. Спасибо, буду знать.
В некоторых ситуациях это действительно может помочь при клонировании. Например, если у нас есть private член, для которого не определено public-свойства (но при этом он используется в каком-либо методе), то без этой фишки не обойтись.

Это сообщение отредактировал(а) Idsa - 3.4.2009, 13:20


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
Madrid
Дата 2.3.2007, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 27.5.2006

Репутация: нет
Всего: нет



Всем привет!Прочитав ваш разговор у меня возник вопрос.


Переменные значимого типа располагаются в стеке!
А переменные ссылочного типа в куче!

1)

Цитата

1) память под элементы массива выделяется в куче, а не на стеке

т.е. переменные значимого типа могут располагаться в куче?

2)
А переменные ссылочного типа могут располагаться в стеке?(К примеру структурная переменая, одним из членов которой является  переменная ссылочного типа).

PM MAIL   Вверх
Idsa
Дата 2.3.2007, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(Madrid @  2.3.2007,  00:13 Найти цитируемый пост)
1) память под элементы массива выделяется в куче, а не на стеке

Это действительно так. Проверить это достаточно просто. Как известно, все значимые типы данных должны наследоваться от класса ValueType. Однако, как гласит MSDN:
Код

public abstract class Array : ICloneable, IList, ICollection, IEnumerable

, Array является прямым неследником Object.

Цитата(Madrid @  2.3.2007,  00:13 Найти цитируемый пост)
т.е. переменные значимого типа могут располагаться в куче?

Цитата(Madrid @  2.3.2007,  00:13 Найти цитируемый пост)
А переменные ссылочного типа могут располагаться в стеке?(К примеру структурная переменая, одним из членов которой является  переменная ссылочного типа).

Да, конечно.
Помимо описанного способа хранения значимых данных в куче через массив, не стоит забывать про boxing/unboxing, когда мы можем при необходимости хранения объекта значимого типа данных в куче (или наоборот) сделать, например, вот так:
Код

int i = 3;
object objInt = i;
...
try
{
 int ii = (int)objInt;
}
catch (InvalidCastException e)
{
 ...
}
}

Да и вообще, возвращаясь к вопросу, могут ли переменные значимого типа храниться в куче, стоит вспомнить, что объекты классов, которые, в частности, содержат значимые типы данных, хранятся в куче.

Это сообщение отредактировал(а) Idsa - 2.3.2007, 01:19


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
ivashkanet
Дата 2.3.2007, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(Madrid @  1.3.2007,  23:13 Найти цитируемый пост)
т.е. переменные значимого типа могут располагаться в куче?

Да. Есть такая операция как запаковка (boxing). Или распаковка smile Я их путаю
Цитата(Madrid @  1.3.2007,  23:13 Найти цитируемый пост)
А переменные ссылочного типа могут располагаться в стеке?

Нет. От ссылочного типа в стеке хранится только ссылка (4 байта) на объект в куче
PM MAIL WWW ICQ   Вверх
Madrid
Дата 2.3.2007, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 27.5.2006

Репутация: нет
Всего: нет



Спасибо!
PM MAIL   Вверх
kurzon
Дата 17.8.2007, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 307
Регистрация: 12.8.2007

Репутация: -8
Всего: -11



А приметивніе типы ето какие типы?
PM MAIL   Вверх
thomas
Дата 17.8.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 6
Всего: 65



kurzon, 
"C# 2005 для профессионалов" стр. 82
"Типы значений и ссылочные типы".


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
ivashkanet
Дата 17.8.2007, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Гугль в руки 

Цитата(http://www.intuit.ru/department/sa/compilersdev/1/5.html)

 Примитивные типы в .NET

.NET поддерживает достаточно большой набор встроенных типов. Только C# поддерживает полный набор примитивных типов .NET. В следующей таблице приведены некоторые встроенные типы данных и объяснено их назначение:

sbyte    System.SByte    Signed 8-bit value
byte    System.Byte    Unsigned 8-bit value
short    System.Int16    Signed 16-bit value
ushort    System.UInt16    Unsigned 16-bit value
int    System.Int32    Signed 32-bit value
uint    System.UInt32    Unsigned 32-bit value
long    System.Int64    Signed 64-bit value
ulong    System.UInt64    Unsigned 64-bit value
char    System.Char    16-bit Unicode character
float    System.Single    IEEE 32-bit float
double    System.Double    IEEE 64-bit float
boolean    System.Boolean    A True/False value
decimal    System.Decimal    96-bit signed integer times 100 through 1028 (for financial calculations)


Добавлено через 1 минуту и 51 секунду
Еще там же:
Цитата

 Примитивные типы

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

string s = "Hello C#";

Эта форма записи удобна, коротка и читабельна. Однако на самом деле, под таким оператором подразумевается следующее присваивание:

System.String s = new System.String(); 
s = "Hello C#";

так как вообще говоря, string является обычным типом, который ничем не отличается от других типов данных. Типы данных, напрямую поддержанные компилятором и допускающие подобные сокращения записи, называются примитивными типами. Примитивные типы преимущественно являются типами-значениями и память под них выделяется на стеке данного потока. Большинство примитивных типов различных языков программирования проецируется на типы данных, существующие в базовой библиотеке классов .NET.

Т.е. можно сказать, что это все что подсвечивается синим в редакторе smile
PM MAIL WWW ICQ   Вверх
thomas
Дата 17.8.2007, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 6
Всего: 65



ivashkanet,  smile 


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
ivashkanet
Дата 17.8.2007, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



thomas,  smile 
PM MAIL WWW ICQ   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0918 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.