I have an object that is generated in one class
public class CreatingClass
{
public T CreateObject<T>(Dictionary<string, object> parameters) where T : IMyInterface, new()
{
....
}
public void DestroyObject(IMyInterface objectToDestroy)
{
....
}
}
I call this function from a client class, then at times need to nullify it through my application by the creating class.
Can I do something like the following
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
}
}
I had tried objectToDestroy = null, but didn't think it would work (and it didn't)
-
What you want is
public void DestroyClass(ref IMyInterface objectToDestroy) { .... objectToDestroy = null; }
This is will set your local reference to null
johnc : Makes complete senseGvS : But will only set one reference to the object to null. The object itself is not destroyed, and other references to it are still valid.DrJokepu : GvS: That's pretty much true for every object in a garbage collected environment. That's why (amongst other reasons) it is a good idea to minimize the number of references to an object. -
[Your 'CreatingClass' is usually termed a factory]
Not sure why you'd be concerned with nullifying an object; it will be garbage collected only after all 'root' references to it have been removed. But if you change to:
public void DestroyClass(ref IMyInterface objectToDestroy) { .... objectToDestroy = null; }
and call as:
private void AFunctionToDeleteMyObject() { CreatingClass.DestroyObject(ref obj); Assert.IsNull(obj); }
-
All parameters in C# are passed by value, so if you want to modify the reference itself, you need to pass it using the
ref
keyword. -
Are you looking for the IDisposable pattern?
-
Note that you can't actually destroy an object; you are subject to the rules of garbage collection. At a push, you could check for
IDisposable
and call Dispose(),You can use the
ref
samples provided, but I'm not sure there is much point; it is simpler just to clear the field with "obj = null;".The
ref
usage could get confusing, since that works on the variable - i.e. if you do:var tmp = obj; DestroyObject(ref tmp);
then
obj
will still be the original value. Unless you have a good reason, I don't recommend theref
approach.Mitch Wheat : +1. Nice reference count example.Marc Gravell : That isn't a "reference count example"; it simple illustrates how "ref" works on the variable not the object... GC doesn't use reference countingBinary Worrier : +1: Far more complete answer than mine.Joe : Also, it's almost always better not to set "obj = null". Just leave the GC to decide when an object is no longer used.Mitch Wheat : @Marc: "reference count " was the wrong words to use. I meant it nicely shows how having a ref stops it being GC'd -
A little clarification on the answers supplied...
Parameters in C# are passed by their type, value for value types, reference for reference types. You however, are passing an interface which could relate to a class (reference type) or struct (value type), therefore you need to explicitly declare it as a ref variable.
However, what you should really follow (as mentioned previously) is the IDisposable pattern, which was designed for this functionality.
EDIT: Parameters are passed by value, but for reference types the reference is the value. Therefore is you destroy the refence in the function, the original reference type is unaffected. If you make a change to the reference variable, i.e. modifying data in a dataset, the original reference type is updated outside of the function.
Jon Skeet : No, parameters are *always* passed by value by default. For reference types, the parameter value *is* the reference - but that's passed by value. See http://pobox.com/~skeet/csharp/parameters.htmlMarc Gravell : "If you make a change to the reference variable, i.e. modifying data in a dataset" - modifying a dataset is modifying the instance, not the variable. There is an important difference.
0 comments:
Post a Comment