Создает ли объект присвоение другому?

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

public aaaaa ad = new aaaaa();

static void Main(string[] args)
{
    Program p = new Program();
    p.fun1();
    p.fun2();
}

public void fun1()
{
    using(smallclass s = new smallclass())
    {
        s.j = 1000;
        ad.fun1(s);
    }
}

public void fun2()
{
    ad.fun2();
}
public class aaaaa
{
    public smallclass h = new smallclass();
    public void fun1(smallclass d)
    {
        h = d;
    }
    public void fun2()
    {
        Console.WriteLine(h.j);
    }
}

public class smallclass:IDisposable
{
    public int j = 9;

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}

Обновление:    Я ожидаю исключение ссылки на объект, так как указанная память расположена в p.fun1 ();

4 голоса | спросил Muthukumar Palaniappan 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 10:01:55 +0400000000amFri, 14 Feb 2014 10:01:55 +040014 2014, 10:01:55

4 ответа


0

Вот простой пример того, как работает раздача

using System;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static smallclass objA = new smallclass();
        private static smallclass objB = new smallclass();

        private static void Main(string[] args)
        {
            showValues();

            objA.value = 1000;

            showValues();

            objB = objA;

            showValues();

            objA.value = 1055;

            showValues();
        }

        private static void showValues()
        {
            Console.WriteLine("objA.value: " + objA.value);
            Console.WriteLine("objB.value: " + objB.value);

            Console.ReadLine();
        }
    }

    internal class smallclass : IDisposable
    {
        public int value = 0;

        public void Dispose()
        {
            //Here you can remove eventHandlers
            //or do some other stuff before the GC will play with it
        }
    }
}

Как вы можете видеть

  1. сначала мы создаем 2 объекта objA и objB
    чем мы показываем значения, как ожидалось, они оба 0

  2. после этого мы увеличиваем значение objA до 1000 значение objA a равно 1000, а значение objB остается на 0

  3. СЕЙЧАС мы учимся objA и objB поэтому значение objB также получило 1000

  4. если мы теперь изменим значение objA на 1055 значение objB также изменилось потому что objB больше не является отдельным объектом, теперь он содержит то же самое ссылка как objA делает

ИЗМЕНИТЬ

А теперь я покажу вам, как вы получаете ошибку на основе вашего примера

измените aaaaa class на:

public class aaaaa
{
    public WeakReference<smallclass> h;
    public void fun1(smallclass d)
    {
        h = new WeakReference<smallclass>(d);
    }
    public void fun2()
    {
        smallclass k;
        if(h.TryGetTarget(out k))
        Console.WriteLine(k.j);
        else
            Console.WriteLine("ERROR ERRROR ERROR");
    }
}

и измените свой static void Main(string[] args) на:

    static void Main(string[] args)
    {
        Program p = new Program();
        p.fun1();
        GC.Collect();
        p.fun2();

        Console.Read();
    }

Хорошо, давайте пройдем через изменения

мы используем WeakReference<T> (вы также можете использовать WeakReference ) если GC теперь натолкнулся на наш объект, он не может найти StrongReference, поэтому может собрать его

теперь ---- +: = 18 =: + ---- Вам нужно позвонить, потому что это заставило GC выполнить свою работу (сейчас, в данный момент)

и помните, как я уже говорил вам ранее > IDisposable будет вызван из GC до того, как он уничтожит объект (AFAIK), поэтому есть место, где можно разместить все, что нужно сделать, прежде чем объект будет уничтожен

ответил WiiMaxx 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 11:42:05 +0400000000amFri, 14 Feb 2014 11:42:05 +040014 2014, 11:42:05
0

Нет, assingning не является "новым" оператором, он копирует .... ссылку, он не создает новый объект. Для класса.

Для структуры это так.

Я предлагаю изучать C #, читая документацию или книгу - эти основы, как правило, обрабатываются до мельчайших деталей.

ответил TomTom 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 10:06:31 +0400000000amFri, 14 Feb 2014 10:06:31 +040014 2014, 10:06:31
0

Вы не ошибетесь, если подумаете, что каждая переменная ссылочного типа, поле, параметр, слот массива или другое подобное хранилище содержит «null» или «object # 24601» [или какое-либо другое число] , Есть только несколько вещей, которые можно сделать с помощью ссылок:

  1. Вы можете создать нулевую ссылку

  2. Вы можете попросить систему создать новый объект и вернуть ссылку на него

  3. Вы можете скопировать одну ссылку на другую

  4. Вы можете проверить, равны ли две ссылки друг другу или одна равна нулю.

  5. Вы можете попросить систему выполнить какое-либо действие над объектом , идентифицированным ссылкой

Если myCar - это переменная некоторого ссылочного типа, например, myCar.Color = CarColors.Blue никак не повлияет на переменную myCar. Вместо этого он обнаружит, что myCar содержит [например] «Объект # 8675309», а затем попросит систему получить доступ к Color свойство или поле объекта # 8675309. И наоборот, если otherCar содержит «объект # 90210», оператор в форме otherCar=myCar ничего не будет делать ни с объектом № 8675309, ни с объектом № 90210, но вместо этого заменит «90210», хранящийся в otherCar с "8675309".

Объекты гарантированно существуют до тех пор, пока существует любая форма ссылки на них, но если есть два объекта, на которые хотя и ссылаются друг на друга, на них нет ссылок чем-то еще во вселенной оба объекта могут одновременно перестать существовать. Это правило является абсолютным, но есть пара поворотов: код может запросить WeakReference к объекту; объект гарантированно существует до тех пор, пока существует слабая ссылка на него, но если система обнаружит, что не существует сильных ссылок на объект, она аннулирует все WeakReference к нему. Кроме того, система ведет список всех объектов, которые хотели бы получать уведомления, если они были оставлены. Если система обнаружит, что этот список содержит единственную ссылку на объект, она переместит объект в список объектов со строгими ссылками, Finalize Метод должен запускаться при первой удобной возможности. При запуске метода Finalize объект будет удален из этого последнего списка. Если за это время нигде не было сохранено ни одной ссылки на объект, объект перестанет существовать.

ответил supercat 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 20:33:06 +0400000000pmFri, 14 Feb 2014 20:33:06 +040014 2014, 20:33:06
0

Я заменил GC.SuppressFinalize на GC.Collect () в функции dispose, однако это не освобождает память .. и в результате я получаю 1000.

Я полагаю, поскольку он содержит другую ссылку (переменную h), GC не освобождает память, даже если мы вызывали ее явно.

Таким образом, мы можем очень хорошо передать и назначить объекты независимо от того, какой выделенный (новый) объект выходит из области видимости.

Пожалуйста, поправьте меня, если я ошибаюсь.

ответил Muthukumar Palaniappan 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 13:46:23 +0400000000pmFri, 14 Feb 2014 13:46:23 +040014 2014, 13:46:23

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132