문제
한 클래스에서 생성된 개체가 있습니다.
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 패턴?
['CreatingClass'를 일반적으로 팩토리라고 합니다.]
왜 객체 무효화에 관심을 갖는지 잘 모르겠습니다.해당 항목에 대한 모든 '루트' 참조가 제거된 후에만 가비지 수집됩니다.그러나 다음과 같이 변경하면:
public void DestroyClass(ref IMyInterface objectToDestroy)
{
....
objectToDestroy = null;
}
다음과 같이 전화하세요.
private void AFunctionToDeleteMyObject()
{
CreatingClass.DestroyObject(ref obj);
Assert.IsNull(obj);
}
제공된 답변에 대한 약간의 설명 ...
C#의 매개 변수는 유형, 값 유형의 값, 참조 유형의 참조로 전달됩니다. 그러나 클래스 (참조 유형) 또는 struct (값 유형)와 관련 될 수있는 인터페이스를 전달하므로 참조 변수로 명시 적으로 선언해야합니다.
그러나 이전에 언급했듯이 실제로 따라야 할 것은이 기능을 위해 설계된 Idisposable 패턴입니다.
편집 : 매개 변수는 값으로 전달되지만 참조 유형의 경우 참조가 값입니다. 따라서 함수의 반박을 파괴하는 것이 원래의 참조 유형은 영향을받지 않습니다. 참조 변수, 즉 데이터 세트에서 데이터 수정을 변경하면 원래 참조 유형이 함수 외부에서 업데이트됩니다.