C # Могу ли я аннулировать объект из другого класса

StackOverflow https://stackoverflow.com/questions/419878

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть объект, который генерируется в одном классе

public class CreatingClass
{
    public T CreateObject<T>(Dictionary<string, object> parameters) where T : IMyInterface, new()
    {
        ....
    }

    public void DestroyObject(IMyInterface objectToDestroy)
    {
        ....
    }
}

Я вызываю эту функцию из клиентского класса, а иногда мне необходимо аннулировать ее через мое приложение с помощью создаваемого класса.

Могу ли я сделать что-то вроде следующего

public class ClientClass
{
    MyObject obj;
    CreatingClass creatingClass = new CreatingClass();

    private void AFunctionToCreateMyClass()
    {
        obj = creatingClass.CreateObject<MyClass>(parameters);
    }

    private void AFunctionToDeleteMyObject()
    {
        CreatingClass.DestroyObject(obj);
        Assert.IsNull(obj);//Doesn't fail
    }
}

Я пробовал objectToDestroy = null, но не думал, что это сработает (и не сработало)

Это было полезно?

Решение

Обратите внимание, что вы не можете уничтожить объект; на вас распространяются правила сборки мусора. Вы можете проверить наличие IDisposable и вызвать Dispose (),

.

Вы можете использовать предоставленные примеры ref , но я не уверен, что в этом есть смысл; проще просто очистить поле с помощью " obj = null; ".

Использование ref может привести к путанице, так как это работает с переменной - т.е. если вы это сделаете:

var tmp = obj;
DestroyObject(ref tmp);

тогда obj по-прежнему будет исходным значением. Если у вас нет веских причин, я не рекомендую подход ref .

Другие советы

То, что вы хотите, это

public void DestroyClass(ref IMyInterface objectToDestroy)
{
    ....
    objectToDestroy = null;
}

Это установит для вашей локальной ссылки значение null

Все параметры в C # передаются по значению, поэтому, если вы хотите изменить саму ссылку, вам нужно передать ее, используя ключевое слово ref .

Вы ищете шаблон IDisposable ?

[Ваш 'CreateClass' обычно называется фабрикой]

Не знаю, почему вас беспокоит обнуление объекта; это будет сбор мусора только после того, как все корневые ссылки на него будут удалены. Но если вы измените на:

 public void DestroyClass(ref IMyInterface objectToDestroy)   
 {       
     ....    
     objectToDestroy = null;
 }

и звоните как:

private void AFunctionToDeleteMyObject()    
{        
   CreatingClass.DestroyObject(ref obj);    
   Assert.IsNull(obj);  
}

Небольшое разъяснение по предоставленным ответам ...

Параметры в C # передаются по их типу, значениям для типов значений, ссылкам для ссылочных типов. Однако вы передаете интерфейс, который может относиться к классу (ссылочный тип) или struct (тип значения), поэтому вам необходимо явно объявить его как переменную ref.

Тем не менее, что вы действительно должны соблюдать (как упоминалось ранее), это шаблон IDisposable, который был разработан для этой функции.

РЕДАКТИРОВАТЬ: параметры передаются по значению, но для ссылочных типов ссылка является значением. Поэтому, если вы уничтожите ссылку в функции, исходный тип ссылки не будет затронут. Если вы измените ссылочную переменную, то есть измените данные в наборе данных, исходный ссылочный тип будет обновлен вне функции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top