How to delete an object on c#? - c#

Is it possible if we delete an object from the class itself? I have a class like below:
Parent Class:
public class ModelBase<T>
{
.....
public void Delete()
{
this = null // <-- it's not works
}
.....
}
Children Class:
public class Company : ModelBase<Company>
{
public string Name;
public Company(string name)
{
Name = name;
}
}
Declaring on UI Layer:
var company = new Company("Company X");
Console.WriteLine(company.Name);
company.Delete();
Console.WriteLine(company.Name); // <-- this should be empty or null
Deleting the object should be on parent class. Is it possible to do that?

No, in C# the garbage collection does the "deleting" for you eventually.
If there`s something inside the class you want to manually dispose like a connection you can use the Disposable Pattern (https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern).
The closest you can come to manually deleting the object is forcing the garbage collector to collect with GC.Collect (https://msdn.microsoft.com/en-us/library/xe0c2357(v=vs.110).aspx).

Obviously setting this to null inside Delete function has not effect outside of the function (if it ever compile).
Destroying an object from itself is also very dangerous as you would have to be sure that no code afterward would access that object (or the caller stack). IN fact, in C#, the idea does not make more sense as it is garbage collected which imply that if you are inside a member function, then you have at least one reference to the object in which case it would never be garbage collected at that point anyway.
Also assuming that the object company was destroyed (and company set to null), you would get a null pointer exception when calling .Name.
Assuming that company object is not disposable (does not implement IDisposable), then your code should look like:
var company = new Company("Company X");
Console.WriteLine(company.Name);
company = null;
Console.WriteLine(company?.Name); // <-- this should be empty or null
Well, we assume that real code is somewhat more complex than that as otherwise you could simply replace last line by:
Console.WriteLine();
However if you company object implement IDisposable, then usually you should use the using keyword if which case setting the object to null would not make sense.
using (var company = new Company("Company X"))
{
Console.WriteLine(company.Name);
}
Console.WriteLine();
Your Delete function is really a bad idea and clearly show a lack of understanding of C#.
If you want to know if an object has been destroyed, you could use WeekReference. As an example, it can be used for a cache. See reference documentation for more information: https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx.
Your whole code make little sense. If you have only one variable, then it is trivial for a decent programmer to know when the object is alive. If you have multiple objects, then you should use a collection (for ex. List<Company>) in which case, you would obviously remove a company from the collection if you don't want it anymore and then when you use that collection, you would not see it anyway.
Alternatively for complexe cases, you might use a dictionary, a set or a flag to remember if you should process a given object. This might be useful for example when iterating a collection as usually you should not modifying while you are enumerating its items.

Related

Am I always dealing with the same object?

I'm working on a TCP socket related application, where an object I've created refers to a System.Net.Sockets.Socket object. That latter object seems to become null and in order to understand why, I would like to check if my own object gets re-created. For that, I thought of the simplest possible approach by checking the memory address of this. However, when adding this to the watch-window I get following error message:
Name Value
&this error CS0211: Cannot take the address of the given expression
As it seems to be impossible to check the memory address of an object in C#, how can I verify that I'm dealing with the same or another object when debugging my code?
In C#, objects are moved during garbage collection. You can't simply take the address of it, because the address changed when the GC heap is compacted.
Dealing with pointers in C# requires unsafe code and you leave the terrain of safe code, basically making it as unsafe as C++.
You can use a debugger like windbg, which displays the memory addresses of objects - but they will still change when GC moves them around.
If you want to see if a new instance of your class gets created, why not set a breakpoint in the constructor?
I am convinced with #thomas answer above.
you can add a unique identifier (such as a GUID) property to your object and use that to determine if you have the same object.
you could override the Equals method to compare two objects if they same as below.
public class MyClass
{
public Guid Id { get; } = Guid.NewGuid();
public override bool Equals(object obj)
{
return obj is MyClass second && this.Id == second.Id;
}
}
As already explained, addresses of objects are not a viable means of reasoning about objects in garbage-collected virtual machines like DotNet. In DotNet you may get the chance to observe the address of an object if you use the fixed keyword, unsafe blocks, or GCHandle.Alloc(), but these are all very hacky and they keep objects fixed in memory so they cannot be garbage collected, which is something that you absolutely do not want. The moment you unfix an object, then its address is free to change, so you cannot keep track of it.
Luckily, you do not need any of that!
You don't need addresses, because all you want is a mnemonic for each object, for the purpose of identifying it during troubleshooting. For this, you have the following options:
Create a singleton which issues unique ids, and in the constructor of each object invoke this singleton to obtain a unique id, store the id with the object, and include the id in the ToString() method of the object, or in whatever other method you might be using for debug display.
Use the System.Runtime.Serialization.ObjectIDGenerator class, which does more or less what the singleton id generator would do, but in a more advanced, and possibly easier to use way. (I have no personal experience using it, so I cannot give any more advice about it.)
Use the System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode( object ) method, which returns what is known in other circles as The Identity Hash-Code of an Object. It is guaranteed to remain unchanged throughout the lifetime of the object, but it is not guaranteed to be unique among all objects. However, since it is 32-bits long, it will be a cold day in hell before another object gets issued the same hash code by coincidence, so it will serve all your troubleshooting purposes just fine.
Do yourself a favor and display the Identity Hash Code of your objects in hexadecimal; the number will be shorter, and will have a wider variety of digits than decimal, so it will be easier to retain in short-term memory while troubleshooting.

How do I dispose this code properly?

I have a quite large project which I try to keep as clean and tidy as possible. When I run the code analyzer in Visual Studio I get a reliability error which I find quite annoying. I'd really like to learn how to work around it. Here is a simplified example of what I am doing.
Here is the warning.
Warning 1 CA2000 : Microsoft.Reliability : In method 'MyExampleClassForStackOverflow.AddFeed(string)', call System.IDisposable.Dispose on object 'new FeedClassExamle()' before all references to it are out of scope.
Here is my example code:
class MyExampleClassForStackOverflow : IDisposable
{
public ConcurrentDictionary<string, FeedClassExamle> Feeds { get; set; }
public void AddFeed(string id)
{
//The warning is coming from this code block.
//In the full code, the feed classes collects data on a specific
//interval and feeds them back using events.
//I have a bunch of them and they need to be accessible so I
//store them in dictionaries using keys to effeciently find them.
Feeds.TryAdd(id, new FeedClassExamle());
Feeds[id].Start();
}
public void Dispose()
{
foreach (var item in Feeds)
item.Value.Dispose();
}
}
class FeedClassExamle : IDisposable
{
public void Start()
{
}
public void Dispose()
{
}
}
In order to test the code, use:
using (var example = new MyExampleClassForStackOverflow())
{
}
Any suggestion would be welcome.
The warning exists because the code analysis tools can't determine whether the object will get disposed correctly. The way your code is written, the object will not in fact get disposed correctly, but fixing the code will likely not eliminate the warning.
Fundamentally, what needs to happen is for every the AddFeed method to ensure that something will call Dispose on every FeedClassExample instance it creates. The best approach is to avoid creating a FeedClassExample instance if one already exists in the dictonary under the present ID. Failing that, the AddFeed method should either dispose of any FeedClassExample it creates but then decides not to store in the dictionary, or else swap with the one that is in the dictionary (I'm not sure what methods ConcurrentDictionary supports to do that) and then Dispose the old one. The essential requirement is that at all times outside the actual execution of AddFeed, the dictionary will hold all instances of FeedClassExample that have been created but not destroyed.
It may be informative to add a destructor in your FeedClassExample class which does nothing except log a message. If you are calling Dispose on that class correctly, the destructor will never execute. If you fail to call Dispose, it will. Thus, if the destructor ever executes, you can know you're doing something wrong.
The object isn't getting Disposed of if TryAdd fails, so try doing this explicitly:
public void AddFeed(string id)
{
FeedClassExample fce = new FeedClassExamle();
if (!Feeds.TryAdd(id, fce))
{
fce.Dispose();
}
Feeds[id].Start();
}
Only create the instance if it needs to be added:
if (!Feeds.ContainsKey(id)) {
Feeds.GetOrAdd(id, new FeedClassExamle());
}

Can someone explain what the point of nulling an object before it goes out of scope is?

I have seen code with the following logic in a few places:
public void func()
{
_myDictonary["foo"] = null;
_myDictionary.Remove("foo");
}
What is the point of setting foo to null in the dictionary before removing it?
I thought the garbage collection cares about the number of things pointing to whatever *foo originally was. If that's the case, wouldn't setting myDictonary["foo"] to null simply decrease the count by one? Wouldn't the same thing happen once myDictonary.Remove("foo") is called?
What is the point of _myDictonary["foo"] = null;
edit: To clarify - when I said "remove the count by one" I meant the following:
- myDictonary["foo"] originally points to an object. That means the object has one or more things referencing it.
- Once myDictonary["foo"] is set to null it is no longer referencing said object. This means that object has one less thing referencing it.
There is no point at all.
If you look at what the Remove method does (using .NET Reflector), you will find this:
this.entries[i].value = default(TValue);
That line sets the value of the dictionary item to null, as the default value for a reference type is null. So, as the Remove method sets the reference to null, there is no point to do it before calling the method.
Setting a dictionary entry to null does not decrease the ref count, as null is a perfectly suitable value to point to in a dictionary.
The two statements do very different things. Setting the value to null indicates that that is what the value should be for that key, whereas removing that key from the dictionary indicates that it should no longer be there.
There isn't much point to it.
However, if the Remove method causes heap allocations, and if the stored value is large, a garbage collection can happen when you call Remove, and it can also collect the value in the process (potentially freeing up memory). Practically, though, people don't usually worry about small things like this, unless it's been shown to be useful.
Edit:
Forgot to mention: Ideally, the dictionary itself should worry about its own implementation like this, not the caller.
It doesn't make much sense there, but there are times when it does make sense.
One example is in a Dispose() method. Consider this type:
public class Owner
{
// snip
private BigAllocation _bigAllocation;
// snip
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
if (_bigAllocation != null)
{
_bigAllocation.Dispose();
_bigAllocation = null;
}
}
}
}
Now, you could argue that this is unnecessary, and you'd be mostly right. Usually Dispose() is only called before Owner is dereferenced, and when Owner is collected, _bigAllocation will be, as well... eventually.
However:
Setting _bigAllocation to null makes it eligible for collection right away, if nobody else has a reference to it. This can be advantageous if Owner is in a higher-numbered GC generation, or has a finalizer. Otherwise, Owner must be released before _bigAllocation is eligible for collection.
This is sort of a corner case, though. Most types shouldn't have finalizers, and in most cases _bigAllocation and Owner would be in the same generation.
I guess I could maybe see this being useful in a multi-threaded application where you null the object so no other thread can operate on it. Though, this seems heavy handed and poor design.
If that's the case, wouldn't setting myDictonary["foo"] to null
simply decrease the count by one?
Nope, the count doesn't change, the reference is still in the dictionary, it points to null.
I see no reason for the code being the way it is.
I don't know about the internals of Dictionary in particular, but some types of collection may hold references to objects which are effectively 'dead'. For example, a collection may hold an array and a count of how many valid items are in the array; zeroing the count would make any items in the collection inaccessible, but would not destroy any references to them. It may be that deleting an item from a Dictionary ends up making the area that holds the object available for reuse without actually deleting it. If another item with the same hash code gets added to the dictionary, then the first item would actually get deleted, but that might not happen for awhile, if ever.
This looks like an old C++ habit.
I suspect that the author is worried about older collections and/or other languages. If memory serves, some collections in C++ would hold pointers to the collected objects and when 'removed' would only remove the pointer but would not automatically call the destructor of the newly removed object. This causes a very subtle memory leak. The habit became to set the object to null before removing it to make sure the destructor was called.

Are .Net property setters ever called implicitly?

I'm on an ASP.Net 2.0 project, in C#. I have some data that gets stored in session state. For ease of use, it is wrapped in a property, like this:
protected IList<Stuff> RelevantSessionData
{
get
{
return (IList<Stuff>) Session["relevant_key"];
}
set
{
Session["relevant_key"] = value;
}
}
Getting and setting the value works exactly as you'd expect. If I want to clear the value, I just set it to null, and there are no problems. However, in another developer's page, he calls the collection's Clear() method. I thought this would be a bug, but it seems to work, and I don't understand why. It works like so:
Debug.WriteLine(RelevantSessionData.Count); //outputs, say, 3
RelevantSessionData.Clear();
Debug.WriteLine(RelevantSessionData.Count); //outputs 0
Why does this work? My naive expectation would be that the middle line loads the serialized value from session, deserializes into an object, calls Clear() on that object, and then lets the unnamed object fall out of scope. That would be a bug, because the value stored in Session would remain unchanged. But apparently, it's smart enough to instead call the property setter and serialize the newly changed collection back into session.
This makes me a little nervous, because there are places in our legacy code where property setters have side effects, and I don't want those getting called if it's not intended.
Does the property setter always get called in a situation like this? Is something else going on? Or do I completely misunderstand what's happening here?
[Added to explain answer]
It turns out did misunderstand. I knew that objects stored in Session must be serializable, and based on that I made too many assumptions about how the collection behaves internally. I was overthinking.
There is only one instance of the stored object (my IList). Each call to the getter returns a reference to that same instance. So the quoted code above works just as it appears, with no special magic required.
And to answer the title question: No, setters are not called implicitly.
Yes, you are right, this would be a bug if your setter/getters were serializing/deserializing the objects. But this is not the case. Instead you are passing based on reference.
So what's basically happening is that the first line in your example gets the item via the get, and Count is called based on that. Then the seccond line is going out and calling get again, returning the same object, running clear, and then the third line is doing the same as the first.
If you had written your setter/getter something like this, you would have a "bug"
protected IList<Stuff> RelevantSessionData
{
get
{
return (IList<Stuff>) JSON.ConvertFromString(Session["relevant_key"]);
}
set
{
Session["relevant_key"] = JSON.ConvertToString(value);
}
}
In this case, a new object would be created and for each call to the get block. But since your example above is simply passing around the reference to the same object, you're not going to see this "bug".
And I say "bug" since it's not really a bug, it's just more of a misunderstanding of what's happening behind the scenes.
I hope this helps.
Your code is roughly equivalent to:
Debug.WriteLine(((IList<Stuff>) Session["relevant_key"]).Count); //outputs, say, 3
((IList<Stuff>) Session["relevant_key"]).Clear();
Debug.WriteLine(((IList<Stuff>) Session["relevant_key"]).Count); //outputs 0
Even if you only call the getter, you are clearing the collection. So the debug output seems normal.
You can expect property setters to be called if:
The are publicly visible (visible to other assemblies).
They implement the setter as part of an interface visible to other assemblies. In some cases, such as
They are used in WPF binding (but the framework will follow the rules about the BindingMode).
They are used in MEF with the ImportAttribute.
They are used in some other binding framework (you get the idea).
You shouldn't run into problems if, for interfaces defined by others, you meet the pre- and post-conditions of the operation.
Edit: I agree with the above. My first choice for exposing a collection is:
private readonly List<T> _sources = new List<T>();
/* Or ICollection<T>, ReadOnlyCollection<T>, or IList<T>, or
* (only a real option for `internal` types) List<T>
*/
public IEnumerable<T> Sources
{
get
{
return _sources;
}
}
If you absolutely must initialize the list after the object is created, then you can use something like this as the second option:
public IList<T> Sources
{
get;
private set;
}
There are situations where the above practices aren't necessarily the best answer, but these are the two most common (IMO?).

How do I determine who is the creator of an object

I have a class that is called regularly by several objects.
I would like to include information in any exceptions as who the creater of the object is.
What are my options?
"Who" refers to an object or class
Store a stacktrace when the constructor is called. This is similar to what SlimDX does in debug builds.
I might be missing something, but I am pretty sure that the only way you can do it, is by manually passing this information, fe. in constructor of your object.
Edit : If this is what you were looking for? :
class Creator
{
public string Name { get; private set; }
public Creator(string name)
{
Name = name;
}
}
class Foo
{
readonly Creator creator;
public Foo(Creator creator)
{
this.creator = creator;
}
public void DoSth()
{
throw new Exception("Unhandled exception. My creator is " + creator.Name);
}
}
public static void Main()
{
Foo f = new Foo(new Creator("c1"));
f.DoSth();
}
If it's only for debugging purposes then add a local string field to the class and assign Environment.StackTrace to it in the class constructor. Then you can include the information in the exceptions as well.
One choice would be to put a "parent" reference into the object:
MyObject myObj = new MyObject(this);
and then use that.
You can try to gather some information from the stack trace in the constructor of your object. You can get the stack frames StackTrace.GetFrames. Then you can walk the stack and try to get the type that a method belongs. If that type is different than the type of your object, you stop walking and store that type information within your object. Then when an exception occurs, you can include that information along with the exception.
Note that this will increase the cost of instantiating your object. So you should consider that and may be put in a mechanism to enable/disable it or include that piece of code only in the debug build.
The question is slightly ambiguous; it really depends what you want. Is this debug information for debug builds, or is it something you will always keep around?
If it's just debug cruft that will be removed in the released product, I'd suggest doing something like this to reduce the pollution of your class(es):
Move the creation into a factory and put the stack inspection code there. This way, the created class doesn't need to care about the stack frame stuff; it is hidden away in the factory.
You can then inject the information via a property setter if you don't mind a little pollution or you could have the factory update a list of created instances + associated creation information for each instance. You can then query this list til your heart is content. Finally, in the release build, you can remove all of this functionality with a couple of #ifdefs.
I'd recommend using the StackTrace object and/or it's GetFrame method. I haven't tried it but it should do what you need it to do w/o having to change every instantiation of the object (assuming you're not using a Factory).
I would imagine something similar to this would work.
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Also note that this appears to be "not quite" a duplicate, but it's close to the question linked above.
Something like this could work to get the calling type:
public class Foo
{
private Type ParentAtCreation = null;
public Foo()
{
ParentAtCreation = (new StackTrace())
.GetFrame(1)
.GetMethod()
.DeclaringType;
}
}
You can use overloaded constructor to that class and a global variable to store that object you receive in that overloaded constructor
e.g if you want an object of class in winforms when you invoke the object to be created you use a overloaded constructor that receives an object of a form
and in the constructor you use this object to store its value in global variable like
When you declare the object as in this case i use a form to open using my currently running form then
Admin_Login ad = new Admin_Login(Enrol, this);
ad.Show();
this.Visible = false;
and make the current form not visible to invoke it again when i want it. I cant dispose it as its the parent of the new form now
and in Admin_Login form i have an overloaded constructor
public Admin_Login(string Enrol,Form parent)
{
Enrollment = Enrol;
Parent = parent;
InitializeComponent();
}
where Parent is my global variable of Form
B.O.L
I'm surprised no one else has said this yet, even as a caveat to their own solution, so I will: this is generally a bad idea, and if you find yourself needing to do it, that's usually a huge indicator that something is very wrong with your design. If you go down this route to solve your problem, you will end up causing far larger issues down the road. Best to take 2 steps back and fix the design that is making this necessary.

Categories

Resources