2009-07-02 4 views
74

소멸자와 클래스의 Finalize 메서드 사이에 어떤 차이가 있습니까?C#에서 클래스의 소멸자와 Finalize 메서드의 차이점은 무엇입니까?

최근에 Visual Studio 2008에서는 Finalize 메서드와 동의어 인 소멸자가 고려됩니다. 즉, Visual Studio에서는 클래스에서 두 메서드를 동시에 정의 할 수 없습니다. 예를 들어

, 다음의 코드 :

class TestFinalize 
{ 
    ~TestFinalize() 
    { 
     Finalize(); 
    } 

    public bool Finalize() 
    { 
     return true; 
    } 
} 

은 소멸자에 마무리하기 위해 호출에 다음과 같은 오류를 제공합니다 :

The call is ambiguous between the following methods or properties: 'TestFinalize.~TestFinalize()' and 'TestFinalize.Finalize()'

그리고

마무리에 대한 호출이 주석하는 경우, 그것을 다음과 같은 오류가 발생합니다 :

Type 'ManagementConcepts.Service.TestFinalize' already defines a member called 'Finalize' with the same parameter types

답변

52

C#의 소멸자가 System.Object.Finalize 메서드를 재정의합니다. 에 소멸자 구문을 사용해야합니다. 수동으로 Finalize을 무시하면 오류 메시지가 나타납니다.

기본적으로 Finalize 메소드 선언을 사용하여 수행하려는 작업은 기본 클래스의 메소드 hiding입니다. 컴파일러가 new 수정자를 사용하여 경고음을 낼 수 있습니다 (작동 할 경우). 여기에서 중요한 점은 있지만, 당신은 모두 override과 너무 소멸자 및 오류가 발생하는 Finalize 방법을 모두 갖는 동시에 동일한 이름을 가진 new 멤버를 선언 할 수 없습니다 (하지만 당신은 을 할 수 있다는 것입니다 추천하지 않는다면 소멸자를 선언하지 않는다면 public new void Finalize() 메서드를 선언하십시오.

16

Found here: http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html

  1. Destructor

    They are special methods that contains clean up code for the object. You can not call them explicitly in your code as they are called implicitly by GC. In C# they have same name as the class name preceded by the ~ sign. Like-

    Class MyClass 
    { 
    
    ~MyClass() 
    { 
    ..... 
    } 
    } 
    

    In VB.NET, destructors are implemented by overriding the Finalize method of the System.Object class.

  2. Dispose

    These are just like any other methods in the class and can be called explicitly but they have a special purpose of cleaning up the object. In the dispose method we write clean up code for the object. It is important that we freed up all the unmanaged recources in the dispose method like database connection, files etc. The class implementing dispose method should implement IDisposable interface.A Dispose method should call the GC.SuppressFinalize method for the object it is disposing if the class has desturctor because it has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method. Reference: http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx

  3. Finalize

    A Finalize method acts as a safeguard to clean up resources in the event that your Dispose method is not called. You should only implement a Finalize method to clean up unmanaged resources. You should not implement a Finalize method for managed objects, because the garbage collector cleans up managed resources automatically. Finalize method is called by the GC implicitly therefore you can not call it from your code.

    Note: In C#, Finalize method can not be override, so you have to use destructor whose internal implementation will override the Finalize method in MSIL.But in the VB.NET, Finalize method can be override because it does support destructor method.

업데이트 :Interesting semi-related thread here.

+0

'관리되지 않는 리소스를 정리하기 위해 Finalize 메서드 만 구현하면됩니다 : Finalize에 넣습니다. Dispose와 같은가요? – hqt

+0

@ hqt : 파이널 라이저를 구현해야하는 곳보다 'Dispose'를 크게 구현해야하는 경우가 훨씬 많습니다. 클래스 또는 파생 클래스의 인스턴스가 관리되지 않는 리소스를 직접 소유하거나 직접 관리되지 않는 리소스를 직접 소유 할 수있는 마지막 것일 가능성이 높거나 마지막으로 직접 소유 한 리소스를 직접 소유하는 경우 Dispose를 구현합니다. 직접 리소스를 소유 할 때만 리소스 정리를 위해 Finalize를 구현하십시오. 직접은 관리되지 않는 리소스 을 소유하고 거의 아무것도 다른 사람이 없습니다 - 훨씬 더 좁은 시나리오입니다. – supercat

+0

@hqt : 하나의 클래스가 관리되지 않는 리소스를 직접 소유하고 다른 객체에 대한 참조를 보유하는 경우 관리되지 않는 리소스는 일반적으로 다른 클래스에 대한 강력한 참조를 보유하지 않는 자체적 인 finalizable 클래스로 분리되어야합니다. 다른 객체에 대한 참조를 보유하는 클래스는 리소스 자체를 소유하는 것이 아니라 "관리되지 않는 리소스를 직접 소유하는 것"만 소유하므로 최종자를 필요로하지 않습니다. – supercat

50

위키 피디 어에는 finalizer 문서의 마무리 자와 destructor의 차이점에 대한 유용한 토론이 있습니다.

C#에는 실제로 "진정한"소멸자가 없습니다. 이 구문은 C++ 소멸자와 비슷하지만 실제로는 파이널 라이저입니다. 당신은 당신의 예제의 첫 번째 부분에서 제대로 쓴 :

~ClassName() { } 

위는 Finalize 기능에 대한 문법 설탕입니다. 기본의 종결자가 실행되도록 보장하지만 그렇지 않으면 Finalize 함수를 재정의하는 것과 동일합니다. 이것은 소멸자 구문을 작성할 때 실제로 최종자를 작성한다는 것을 의미합니다. 소멸자 결과 (Finalize가되는 문법적)로 실행 된 코드의 비트가 동시에

According to Microsoft

는 파이널, 그것은 ( Finalize) 수집되면 가비지 수집기가 호출하는 기능을 말한다. 그들은 마이크로 소프트가 구별하지 말아야 할 것과 매우 가깝다.

마이크로 소프트의 C++의 "소멸자"용어는 오해의 소지가 있습니다. 왜냐하면 C++에서는 객체가 삭제되거나 스택에서 꺼내 자마자 동일한 스레드에서 실행되기 때문에 C#에서는 별도의 스레드에서 실행됩니다. 다른 시간.

+0

나는 소멸자와 파이널 라이저 (finalizer)의 구분이 중요한 부분이라고 주장한다. 그러나 후드 아래에서 진행되는 작업을 신경 쓰는 사람 만이 상기 구별에 관심을 가질 것입니다. –

+0

또한 주목하십시오. ECMA-334는 오래전부터 공식적으로 "소멸자"와 "최종 자"를 명시 적으로 명확하게했습니다. 나는 왜 MS가 여전히 자신들의 사양에서 오해의 소지가있는 용어를 주장하는지 모르겠다. – FrankHB

+0

적어도 Mono를 사용하여 C#은 실제로 C++ 이후 모델링되었으며 대부분의 네이티브 C# 개체는 C++ 개체입니다. Mono 작품을 컴파일 한 컴파일러는 어떻게 C++ 객체가 파괴되는지를 지시하고 마찬가지로 C# 객체 마무리를 C++로 전파하여 소멸자를 호출합니다. 구별은 구별하기에는 적합하지만 C# 자체에는 여전히 적용되지 않습니다. – Kenzi

관련 문제