7

In C++, it is possible to delete this and set its own reference to null.

I want to set an object instance to null itself.

public class Foo
{

    public void M( )
    {
       // this = null; // How do I do this kind of thing?
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1924210
  • 97
  • 1
  • 1
  • 3
  • You can only set references that point to the object to null. – Erik Eidt Dec 22 '12 at 22:16
  • This doesn't make sense, the only purpose it would serve is to prevent usage of 'this'. All the other references would still point to the instance. – Dave Hillier Dec 22 '12 at 22:17
  • 2
    are you sure you need that? it is not possible in c#, what are you trying to do? – Arsen Mkrtchyan Dec 22 '12 at 22:17
  • I want to use it like example usage below:Foo f= new Foo(); f.M(); if (f==null) { Console.WriteLine("somethig to do"); } – user1924210 Dec 22 '12 at 22:18
  • 1
    You cannot call `f.M()` if `f` is `null`. This simply doesn't make any sense. Your program will crash much before the `M` method is invoked. It makes strictly no sense to check inside the `M` method if the current instance is null because you wouldn't even be able to call this method if this is the case. – Darin Dimitrov Dec 22 '12 at 22:21
  • I want to set current reference to null in M(). then I will control if it is null – user1924210 Dec 22 '12 at 22:23
  • 2
    You don't have access to the variable that holds a reference to `f` from within `M()`. You just don't. Find another way to achieve your goal. Or, tell us what that goal is. – Michael Petrotta Dec 22 '12 at 22:24
  • In C++, "delete this" like operation is allowed. I want to do that kind of usage in c# – user1924210 Dec 22 '12 at 22:25
  • 3
    You can't. End of story. Sorry. Why do you want to do this? What's your use case? We might be able to help with that. – Michael Petrotta Dec 22 '12 at 22:25
  • I am trying to use it in a binary search tree recursive implementation. I need =null or Dispose or etc in C# – user1924210 Dec 22 '12 at 22:28
  • Well, now, dispose you can do! [Very common](http://stackoverflow.com/questions/898828/c-sharp-finalize-dispose-pattern) [pattern](http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx) in .NET. – Michael Petrotta Dec 22 '12 at 22:29
  • IDisposable only adds dispose method. I could not dispose current instance in M(). public class Foo : IDisposable { public void M() { //this =null; } public void Dispose() { } } – user1924210 Dec 22 '12 at 22:30
  • I really do recommend that **you tell us what larger problem you're trying to solve**. You keep circling back to deleting an object from within itself, without telling us why. Maybe read the links I posted, and come back if they don't trigger any ideas. But **tell us why you think you need to do this**. Be expansive. – Michael Petrotta Dec 22 '12 at 22:33
  • ok. I pasted my whole code to http://pastie.org/5566607 it it my binary search tree implementation. i can not remove root node. I also read the dispose pattern. I do not want to call any other methods like obj.dispose() – user1924210 Dec 22 '12 at 22:43
  • If you're sure you want to, then have another object (a `Tree` class or something) hold a reference to the root node. Null it out from there. – Michael Petrotta Dec 22 '12 at 22:47
  • Why would you want the object to set itself to null? Wouldn't it be better to do it in the place the object is used? – detrumi Dec 22 '12 at 22:16
  • Why? I agree that you'd want to set it where it is used. – Dave Hillier Dec 22 '12 at 22:18
  • I want to use it like example usage below:Foo f= new Foo(); f.M(); if (f==null) { Console.WriteLine("somethig to do"); } – user1924210 Dec 22 '12 at 22:21
  • @SonerGönül You're right, I should have posted this as a comment to the original question. – detrumi Dec 22 '12 at 22:24
  • there should be a wrapper for this node class to achive its goal but actually I am trying to find a "delete this" equivalent in c# like c++. – user1924210 Dec 22 '12 at 23:02
  • 2
    You can't. Find another way. We're not lying to you. – Michael Petrotta Dec 22 '12 at 23:05
  • sure. thanks a lot for your answers and also patience. – user1924210 Dec 22 '12 at 23:09
  • Don't use the comments to improve your question. Also don't post the code somewhere else. Just add it to your question. This helps others to understand your problem without reading through a long list of comments. People cannot even answer your question in a proper way if any hints leading to an answer are hidden somewhere in the comments. – pescolino Dec 22 '12 at 23:17
  • 1
    @user1924210: For completeness, the definitive answer is Raymond Chen's blog post [When does an object become eligible for garbage collection?](http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx) You might also want to read the related [Everybody thinks about garbage collection the wrong way](http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx). – Daniel Pryden Dec 23 '12 at 03:32

4 Answers4

9

this is actually just a special name given to the parameter, arg0, in an instance method. Setting it to null is not allowed:

  1. you cannot ever change this for instance methods on a class
  2. you can change this for instance methods on a struct, but you can't assign null

The reason for 1. is that it would not be useful:

  • the parameter arg0 is by-val (not by-ref) on class instance methods, so the method's caller won't notice the change (for completeness: arg0 is by-ref on struct instance methods)
  • it won't really change memory management in any way:
    • setting something to null does not delete it; the GC handles that
    • if there are external roots holding a reference to the object, they will still be holding a reference to the object
    • if you are worried about the edge-case of the parameter being the last root to the object, then just exit the method

So basically, that syntax is not allowed, because it doesn't do what you want. There is no C# metaphor for what you want.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
8

This is not possible in .NET. You cannot set the current instance to null from within the object itself. In .NET the current instance (this) is readonly, you cannot assign a value to it. And by the way that's not something you would even need in .NET.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
3

In C++ delete this frees the memory of the object. There is no equivalent to that in C# (or any other .NET language). Although it is allowed in C++ I don't think it's a good practice. At least you have to be very careful.

.NET uses garbage collection instead to free memory. Once an object isn't referenced any more and cannot be accessed from anywhere in your code the garbage collector can eventually free the memory (and the garbage collector is careful). So just lean back and let the garbage collector do its work.

pescolino
  • 3,086
  • 2
  • 14
  • 24
  • 1
    I think you should replace "will" with "can" in the sentance *Once an object isn't referenced ... the garbage collector will free the memory*. The way you wrote it makes it sound like deallocation is more deterministic than it actually is. – Conrad Frix Dec 23 '12 at 00:02
0

Simply no. As this is not possible to access a method from a null object. In your case you want say

F f = new F() // where f = null
f.SomeMethod(); // ?????? not possible

In this case you get a Null Reference Exception. You can see Darin's Comment and Explanation too on the same. How could you access anything from null, which means nothing. I have no idea about legacy but .Net does not provides you such things. Instead you can set it to null when its not needed anymore.

Ex From MSDN

public class Node<T>
{
        // Private member-variables
        private T data;
        private NodeList<T> neighbors = null;

        public Node() {}
        public Node(T data) : this(data, null) {}
        public Node(T data, NodeList<T> neighbors)
        {
            this.data = data;
            this.neighbors = neighbors;
        }

        public T Value
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }

        protected NodeList<T> Neighbors
        {
            get
            {
                return neighbors;
            }
            set
            {
                neighbors = value;
            }
        }
    }
}


public class NodeList<T> : Collection<Node<T>>
{
    public NodeList() : base() { }

    public NodeList(int initialSize)
    {
        // Add the specified number of items
        for (int i = 0; i < initialSize; i++)
            base.Items.Add(default(Node<T>));
    }

    public Node<T> FindByValue(T value)
    {
        // search the list for the value
        foreach (Node<T> node in Items)
            if (node.Value.Equals(value))
                return node;

        // if we reached here, we didn't find a matching node
        return null;
    }
}

 and Right—that operate on the base class's Neighbors property.
public class BinaryTreeNode<T> : Node<T>
{
    public BinaryTreeNode() : base() {}
    public BinaryTreeNode(T data) : base(data, null) {}
    public BinaryTreeNode(T data, BinaryTreeNode<T> left, BinaryTreeNode<T> right)
    {
        base.Value = data;
        NodeList<T> children = new NodeList<T>(2);
        children[0] = left;
        children[1] = right;

        base.Neighbors = children;
    }

    public BinaryTreeNode<T> Left
    {
        get
        {
            if (base.Neighbors == null)
                return null;
            else
                return (BinaryTreeNode<T>) base.Neighbors[0];
        }
        set
        {
            if (base.Neighbors == null)
                base.Neighbors = new NodeList<T>(2);

            base.Neighbors[0] = value;
        }
    }

    public BinaryTreeNode<T> Right
    {
        get
        {
            if (base.Neighbors == null)
                return null;
            else
                return (BinaryTreeNode<T>) base.Neighbors[1];
        }
        set
        {
            if (base.Neighbors == null)
                base.Neighbors = new NodeList<T>(2);

            base.Neighbors[1] = value;
        }
    }
}


public class BinaryTree<T>
{
   private BinaryTreeNode<T> root;

   public BinaryTree()
   {
      root = null;
   }

   public virtual void Clear()
   {
      root = null;
   }

   public BinaryTreeNode<T> Root
   {
      get
      {
         return root;
      }
      set
      {
         root = value;
      }
   }
}
  • Firstly this was working as c++ code. I did not need any wrapper. I operated on node class. I ported it to c# but I could not find any "delete this" equivalent to implement. I read msdn BST article before. – user1924210 Dec 22 '12 at 22:59