C # Могу ли я аннулировать объект из другого класса - PullRequest
3 голосов
/ 07 января 2009

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

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, но не думал, что это сработает (и не сработало)

Ответы [ 6 ]

7 голосов
/ 07 января 2009

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

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

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

var tmp = obj;
DestroyObject(ref tmp);

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

5 голосов
/ 07 января 2009

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

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

Это установит локальную ссылку на ноль

3 голосов
/ 07 января 2009

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

3 голосов
/ 07 января 2009

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

2 голосов
/ 07 января 2009

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

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

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

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

private void AFunctionToDeleteMyObject()    
{        
   CreatingClass.DestroyObject(ref obj);    
   Assert.IsNull(obj);  
}
0 голосов
/ 07 января 2009

Небольшое уточнение по предоставленным ответам ...

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

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

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

...