3

I've been looking for this info for a loooong time. Never seen anyone asking stuff like this before. I know that we can use pointer in C# inside unsafe code, but thats not the case. The problem is:

MyClass beta = new MyClass();
MyClass alpha = beta;
beta = null;

What I need to do now is set beta to null and ALSO set alpha to null. Let's say that i have returned alpha in a function, so I dont have access to it anymore, so, how can I set it to null? In c++ if beta and alpha were pointer I could just free the memory that beta points to, but I dont know a way to do that in c#.

In a more basic way, lets say that I have to set both variables to null, but i have acces only to one of them.


Edit

I did see some answers that have nothing to deal with the question i did... Ill try to explain again. I'm creating a class that do some motion effect and return a instance that can be used to pause or stop this motion. The programmers that use this class are used to test variables with if(variable != null) before using it. What i need is when the motion is over the instance they have is turned into null, so they know that its not usefull anymore.

Is there any way of doing it?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
  • 3
    You don't need to "free" it, the Garbage Collector will do it for you. – DaveShaw Jan 16 '13 at 20:39
  • 2
    My first question to you about this is why? As @DaveShaw said above, the Garbage Collector will do it for you. – Brian Jan 16 '13 at 20:39
  • The point would be so that the other variable *cannot* access the underlying object, even though that variable hasn't gone out of scope. – Servy Jan 16 '13 at 20:42
  • what?? I guess you are not used to managed code. these references will be garbage collected once they get out of scope and no longer needed – Federico Berasategui Jan 16 '13 at 20:43
  • @HighCore I guess you're just not familiar enough with unmanaged code to understand the implications of his analogy, and are incorrectly assuming he is misunderstanding managed code. – Servy Jan 16 '13 at 20:44
  • Posting the actual code where you have this issue might help – Joanna Derks Jan 16 '13 at 21:06

4 Answers4

10

You need to add an additional layer of indirection. To put things in C++ terms, MyClass is a pointer to an object, so to set both pointers to null you need to be passing around pointers to pointers instead, so that you can resolve the pointer to pointer to just a pointer, set that to null, and both double pointers will resolve to null.

Adding an extra layer of indirection in C# usually means creating a new class.

public class Wrapper<T>
{
    public T Value { get; set; }
}

Using that, we can make alpha and beta each be Wrapper<MyClass> objects (make sure they are both the same instance of Wrapper), and to affect both "pointers" you can just set Value of the Wrapper to null.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • +1, There is definitely lack of generics here. I wish there were some lambda with recursive delegates in your answer. – Ilya Ivanov Jan 16 '13 at 20:42
  • +1, this is good approach, also it does not match C++ AV/undefined behavior on accessing deleted object via stale pointer :) – Alexei Levenkov Jan 16 '13 at 20:46
  • @AlexeiLevenkov As I stated in the first paragraph, the appropriate analogy in C++ would be to have a double pointer, or a reference to a pointer (which would be an option in C# to if you needed to access a variable from an "outer" scope, not an inner scope). In C++, that's how I would solve this problem (to avoid said problems with accessing a deleted object). – Servy Jan 16 '13 at 20:47
  • Yes, but it pointer-to-pointer is not what was suggested in OP's question as desired C++ behavior (or at least how I read it:" In c++ if beta and alpha were pointer I could just free the memory that beta points to") – Alexei Levenkov Jan 16 '13 at 20:52
  • Objects never go out of scope in C# as they do in C++. They are dealt with by the Garbage Collector automatically when they are not used anymore. This is a more complicated approach than C++ where the scope of a variable is entirely deterministic. CLR garbage collector actively goes through all objects that have been created and works out if they are being used. – Mustafa Ekici Jan 16 '13 at 20:57
  • @AlexeiLevenkov His analogy succeeded in explaining to me what his wanted to accomplish. He didn't state that it's what he's doing in a C++ progam that he wants to replicate, or even that it's a good idea in any C++ program. The analogy succeeded at what it was meant to do (for me; apparently 8 other people have taken the analogy the wrong way, which is unfortunate). – Servy Jan 16 '13 at 20:57
  • 1
    @MustafaEkici Which is irrelevant to the question at hand. It's unfortunate that you took the OP's analogy too literally and failed to think about what he was really trying to say, as opposed to just how he said it. The answer to this question has nothing, whatsoever, to do with the garbage collector, the collection of objects, or `IDisposable`. (Well, `IDisposable` is a possible hack in the event the answer I provided can't be implemented due to restrictions in what can be edited.) Oh, and for the record, variables do have scope, it's the objects those variables reference that may not. – Servy Jan 16 '13 at 20:59
  • I actually don't know what OP wants to accomplish, but agree that your understanding of the question is very reasonable, as well proposed solutions for C# and C++ are good. On other hand maybe OP just looking for `void Foo(ref MyClass arg){... arg = null; }` and all this discussion is unrelated... would be so much easier if OP would comments :) – Alexei Levenkov Jan 16 '13 at 22:00
0

Unless your class contains a disposable object there isn't a need to Dispose of the object, and setting it to null simply makes the object null which doesn't free memory but instead would help if you need to check the object later...

If your class needs to be marked as disposable because it needs to clean up it's memory usage please look into making your class inherit from the IDisposable! interface.

abc123
  • 17,855
  • 7
  • 52
  • 82
0

If you need to get some sort of AV/exception (to match C++ behavior of accessing deleted object) the closest you can get is make object IDisposable and make all methods/properties to thrown after object is disposed (similar to how Stream-derived objects behave).

MyClass beta = new MyClass();
MyClass alpha = beta;
beta.Dispose();

alpha.Method(); // should throw  ObjectDisposedException.
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
0

You don't need to do either. C# memory is automatically managed, so things get freed when there are no more references to them. If you specifically want to free something because you've caught an OutOfMemoryException, then yes, you can start setting things to null and forcing the garbage collector as @JanesAbouChleih points out. It is much better to call the .Dispose method and implement any other clean up code MyClass may require (closing files, flushing buffers, etc.).

Some references:

http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

http://msdn.microsoft.com/en-us/library/ms973837.aspx

Also, similar question on how/when/why to dispose things: Do you need to dispose of objects and set them to null?

Community
  • 1
  • 1
Patrick M
  • 10,547
  • 9
  • 68
  • 101