Есть вот такой пример кода:
public void DoActions(UserClass MyClass)
{
//Actions with MyClass
}
Как поведет себя GC если я проинициализирую UserClass прямо в аргументах метода? Т.е. :
DoActions(new UserClass());
Правильно ли я понимаю, что GC "подчистит" объект при выходе из метода/при очередной сборке мусора? А если объект будет содержать управляемый ресурс из внешней библиотеки? Достаточно ли будет реализации в UserClass метода Dispose и деконструктора для очистки этого ресурса? Т.е. например вот так:
public class UserClass : IDisposable
{
public ClassFromExtendLibrary Memory; //Например какой-нибудь класс из внешней библиотеки реализующий внутри интерфейс IDisposable
public int[] SomeArray;
private bool _disposed = false;
//some code
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(_disposed) return;
if(disposing)
{
SomeArray = null;
Memory?.Dispose();
}
_disposed = true;
}
~UserClass()
{
Dispose(false);
}
}
UMemory?.Dispose();можно вызывать только еслиdisposing = true. Правило: finaliser не трогает объекты .NET. Возникает вопрос: а что тогда вообще может делать finaliser? Освобождать native resources, напримерMarshal.FreeHGlobal. – Alex F May 19 '22 at 08:02SomeArray = nullвDispose- это лишнее, GC сам разберется с неуправляемыми объектами. – Alex F May 19 '22 at 08:05Disposeу внутреннего управляемого объектаMemory, если я не вызовуDisposeуMyClassв методеDoActions, ведь финализатор его не вызовет. – Diesel May 19 '22 at 08:14UserClassв аргументах методаDoActions()? – Diesel May 19 '22 at 08:16Memory?.Dispose();, тоMemoryосвободит свои ресурсы только в своем финализаторе. А это произойдет через некторое время, когда GC решит. То есть, вместо очистки ресурсов немедленно и синхронно (Dispose) вы получите очистку "через какое-то время". Все это при условии, что классMemoryреализован правильно. – Alex F May 19 '22 at 08:25Memory(при правильной реализации) внутри имеет неуправляемый ресурс(IntPtr) и финализатор - который и будет во внутреннем методеDisposeосвобождать этот ресурс. А GC(после выхода из методаDoActions) уже сам решит когда вызвать финализатор уMemory. Благодарю @AlexF c; – Diesel May 19 '22 at 08:38