Tell if an instance is pointed to by other variables? - c#

This is a longshot but...
I understand there is a way to tell if variable A (var1, var2...., varX) points to instance of class by using Equals:
List<string> _mainInstance = new();
var var1 = _mainInstance;
var var2 = _mainInstance;
var var3 = _mainInstance;
//I understand how to tell if variable points to _mainInstance
if (var1.Equals(_mainInstance))
{
//It does because it points by reference
}
//I want to check if any variable still point to _mainInstance
if (!_mainInstance.HasOthersPointingToIt())
{
//Safe to delete _mainInstance
}
I don't know at design time how many pointers to _myInstance there will be. I want to check if my _mainInstance has any variables still pointing to it every so often. I thought maybe reflection or garbage collection but all my research there is coming up with nothing.
Is there a way to examine a variable (in this case an instance of a class) and tell if anything else (variables, properties of a class instance) still point to it?
Edit:
#GuruStron asks what is the underlying problem I am trying to solve?
Answer: I have a parent/child "tree" that I need to keep track of. That in itself is pretty easy. My difficulty is that the tree has blocks that have a single definition and that definition gets reused.
In the graph below it shows the top tree with stars. The stars represents pointers to block definitions. Below that on the left are the actual block definitions.
The the block definition gets substituted and the final tree looks like this:
When a block pointer is deleted I need to make sure that nothing else is pointing to that block definition and delete the block definition when it is no longer needed.

Related

Difference between assigning object to variable and passing it as argument VS directly creating object and passing it in argument

What is the difference in both and which is recommended and why?
var getDetailsReq = new getTransactionDetailsRequest
{
transId = transactionResponse.Payload.Id
};
var getDetailsCont = new getTransactionDetailsController(getDetailsReq);
vs
var getDetailsCont = new getTransactionDetailsController(new getTransactionDetailsRequest
{
transId = transactionResponse.Payload.Id
});
The first one holds the address of the object in the memory and it will clean out when dispose off
The second one will go untraceable and will be lost somewhere in memory
makes sense or do you have something to correct me?
They are functionally equivalent if the reference is not use again by the caller. It's very possible the optimizer will remove the temporary variable anyway if it is not used by the calling scope.
The second one will go untraceable and will be lost somewhere in memory
Well, you pass it to getTransactionDetailsController, so presumably it does something with the reference. Once the garbage collector detects that no objects have a reference to the object, it will be garbage collected (not disposed).
So use whichever one you feel is better - there is no practical guidance that I know of.
Performance wise? Nothing.
Readability-wise? I'd argue that the first one is more readable and maintainable than the second one:
You can set a breakpoint on the appropriate constructor when debugging.
You can easily inspect / watch the values of getDetailsReq.
If you need getDetailsReq somewhere else in your code, use method 1. Otherwise, it shouldn't make a difference

Can't figure out how this method produces garbage and how to fix it

I've got a method that I'm calling ... well, very often. And now the GC is becoming a problem, because apparently this method is creating garbage, but I can't seem to figure out why.
Item item;
foreach (Point3D p in Point3D.AllDirections)
{
item = grid[gridPosition + p];
if (item != null && item.State != State.Initialized)
else
return;
}
OtherMethod(this);
This method is inside the Item class and figures out the state of neighbouring items. The gridPosition variable is obviously the position of this item inside the grid and the Point3D is a struct that just contains 3 ints, one for each axis. It also contains a few predefined static arrays such as AllDirections which itself only contains Point3Ds.
Now, the state of items can change at any time and once all neighbours have a specific state (or rather aren't in the Initialized state) I do some other stuff (OtherMethod), which also changes the state of the item so this method is no longer called. As such the produced garbage is only a problem when neighbours don't change their state (for example when there is no user input). I guess you could think of this as a substitution for an event driven system.
I admit that I have a rather limited understanding of memory management and I tend to only really understand things by doing them, so reading up on it didn't really help me much with this problem. However, after reading about it I got the impression that every value type, that is defined within a method and doesn't leave it, will be collected upon leaving the method. So I have a little trouble figureing out what's actually left after the return.
Any ideas on what's actually generating the garbage here ? Of course the best case would be to produce no garbage at all, if at all possible.
(Just in case this is relevant, I'm working in Unity and the method in question is the Monobehaviour Update)
Edit for all the comments:
Holy cow you guys are quick. So...
# Jeppe Stig Nielsen: There is nothing between if and else, there was once but I didn't need that anymore. It's just a quick way to leave if no neighbour was found. Also, Indexer ! Completely forgot about that, here it is:
public Item this[Point3D gridPosition]
{
get
{
Item item;
items.TryGetValue(gridPosition, out item);
return item;
}
}
Could the TryGetValue be the reason ?
# Luaan: I already tried a normal for loop, didn't change anything. That looked something like this:
for (int i = 0; i < 6; i++)
{
item = grid[gridPosition + Point3D.AllDirections[i]];
}
If it was the enumerator, that should've fixed it, no ?
# Rufus: Yes that's a better way to write the if, will fix that. The whole thing is a work in progress right now, so that's just a remnant of past experimentation. There is currently is nothing else in the if statement.
# Tom Jonckheere: Well there isn't really much else. It's just Unitys Update() followed by two if statements for the State. And that's really just because I currently only work with two states but have already setup more, so someday there will probably be a switch instead of ifs.
# Adam Houldsworth: Well yes, the problem is certainly that I call it so often. The odd thing is, the amount of garbage produced varies wildly. As far as I can tell it's in the range of 28 bytes to 1.8KB. As for the whole red herring thing, I don't think that's the case. The profiler points to the Update method, which only contains two ifs, one which is the code from above, the other one isn't being used when no state changes occur. And when testing, there are no state changes, except for intial setup.
Also, sorry for the wrong tag, first time I've visited this site. Looks like I'll have some reading to do :)
foreach calls GetEnumerator, which, in turn, creates a new instance of Enumerator every time it's called.
So after Jeppe Stig Nielsen and Luaan made me remember that I'm infact using an indexer I did some googleing and found out that this is not a new issue. Apparently Dictonary.TryGetValue works by calling Equals(object o) on the keys. Now these have to be unboxed which, as far as I understand it, creates the garbage. I now followed the advice I found on Google and implemented the IEquatable interface in my Point3D struct, which does not requiere any boxing. And as it turns out, a big chunk of the garbage is gone.
So the generated garbage per call went from ~28B-1.8KB down to ~28B-168B. Which is pretty good, no more GC spikes. Though I'm still curious where the rest of the garbage is coming from.
Anyway, this was already a big help, so thanks for your answers guys.
Edit: Figured out where the rest of the garbage was comeing from. I just called base.GetHashCode, because I didn't know any better. I did some research into pretty much everything related to hash codes and then implemented it correctly. And now I'm down to exactly 0 bytes of garbage. Pretty neat.

C# XNA - I want to access the Board(instance of a class) that this particular Block(instance of a class) exists in

I thought about it for a long time, and I couldn't come up with a better title. I'm not sure what specific thing I need to figure out in order to solve this problem. This is the code I have minus anything I think is unnecessary for this question.
static class GameManager
{
public static List<Board> Boards = new List<Board>();
// let's say there are 2 boards
}
class Board
{
public Dictionary<Vector2, Block> Blocks = new Dictionary<Vector2, Block>();
//each board has a bunch of blocks in it.
{
class Block
{
//I want to access the Board that this particular Block exists in.
}
See, I used to have just one board, so if I was a block in the block class, and I wanted to access, say, the number of blocks in a board, I could just use GameManager.Board.Blocks.Count. I wanted to add multiplayer, so I made a list of boards each with their own set of blocks. Now I need to somehow make a block know which board it's in.
Is there maybe a way I can go backwards in terms of accessing different levels of code? For example, if I started at GameManager, I could go forward through levels by saying GameManager.Boards[0].Blocks[new Vector2(0, 0)] with a . for every level I go down. If I'm starting at the Block class, am I able to go up to access the particular instance of Board that the current instance of Block exists within? I don't want to turn this into an XY problem so what do you think I should do? It seems like storing and passing a variable that keeps track of the current board that's being updated is sloppy code because each block should already know which board it exists in since I did in fact initiate multiple boards each containing their own separate set of blocks. Do you think perhaps I need to nest the Block class within the Board class?
Given your design, there is no direct way for a block to know which board its in. In general, this is a good thing. Why would a block need any knowledge of its board?
But, you could write this (as is):
var parent = GameManager.Boards.FirstOrDefault(b => b.Blocks.Values.Contains(this));
Now that's pretty inefficient, and not very pretty. You could also just pass the board to the block when you create it and hold it in a parent field of the Block class. This is much more speed efficient, at the cost of an extra variable per block.
In reality though, classes rarely if ever need to know about what is holding them. Think carefully to determine if this is actually a requirement for your game.

Understanding Lists of Objects

Was introduced to the concept of the generic List<>. Consider the following
// Create an instance of the Theater class.
this.MarcusTheater = new Theater();
// Set the field values of the Theater.
this.MarcusTheater.Screens = new List<Screen>();
this.MarcusTheater.Screen1 = new Screen();
// Set the field values for Screen1.
this.MarcusTheater.Screen1.Lenght = 23;
this.MarcusTheater.Screen1.Width = 50;
// Add Screen1 to the Screen list.
this.MarcusTheater.Screens.Add(this.MarcusTheater.Screen1);
From my understanding Screen1 is a temporary holder for the Screen instance. Once added to the list it becomes indexed within that list and isn't really Screen1? Since the instance of the Screen object is being stored within the Screen List, can I pull back this object in it's entirety? If so what is the best way to loop through a list<> of Screens in order to find Screen1? I know this might seem like a trivial question but I'm trying to nail down the basics. Thank you in advance.
From my understanding Screen1 is a temporary holder for the Screen
instance.
Kind of. It's is a "holder", but it's not temporary. Even when you add Screen1 to ScreenList, Screen1 is still valid. You've just copied the reference to that object. Figure this:
this.MarcusTheater = new Theater();
this.MarcusTheater.Screens = new List<Screen>();
this.MarcusTheater.Screen1 = new Screen();
// <your stuff here>
this.MarcusTheater.Screens.Add(this.MarcusTheater.Screen1);
Screen1 thisIsTheSameScreen = this.MarcusTheater.Screens[0];
At this point, this.MarcusTheater.Screen1 and thisIsTheSameScreen point to the same object. We're just passing its reference around.
So, if we did something like
thisIsTheSameScreen.Lenght = 20;
We would be changing for everyone, because it's the same object.
Once added to the list it becomes indexed within that list and isn't
really Screen1?
No. It's still the same, we are simply sharing the reference.
Since the instance of the Screen object is being stored within the
Screen List, can I pull back this object in it's entirety?
Sure, just like I did above.
If so what is the best way to loop through a list<> of Screens in
order to find Screen1?
You need a way to identify each screen, like an ID or a name. This way you can iterate that list and fetch the one you're looking for, either using Linq or a simple foreach.
I know this might seem like a trivial question but I'm trying to nail
down the basics. Thank you in advance.
And you're perfectly correct. We all should understand the tools we're using.
I would suggest that you think of class-type storage locations (fields, parameters, array elements, etc.) as holding "object IDs". The statement someScreen.Width = 123; doesn't change someScreen. If, before that statement executed, someScreen identified the 24,601st object that was created since the program started, the statement will ask object #24601 to set its Width property to 123, and leave someScreen referring to object #24601. If one says someList.Add(someScreen), and someList identifies the 8,675,309th object, then, then object #8675309 will be asked to add "object #24601" to itself. Note that the actual object #24601 will not be added to the list--merely its identity.
(I'm unaware of .NET providing a means by which one could determine which object was created between the 24,600th and 24,602nd objects, but if more than 24,602 objects have been created, exactly one such object must exist; during that run of the program, that object can never be anything other than the 24,601st object, nor can any other object ever be the 24,601st; if one accepts hypothetically that a particular object is the 24,601st one created, then "object #24601" may, within that hypothetical context, be used to refer to the object in question.)
Screens is not a temporary screen, it is the one and only instance. When you add it to the list a pointer or reference to screen 1 is made. If you were to modify screen 1 via either the instance or the list, both instances would change in step.
You should have a read about references, and possibly c++ pointers and that should help you understand.
Yes, the objects are reference types and therefore both variables will point to the same object in memory, there's a dead easy way to test this. You can use the Object.ReferencesEquals method to determine if they reference the same object.
Screen screen1 = new Screen();
screen1.Length = 23;
screen1.Width = 50;
Screen screen2 = new Screen();
screen2.Length = 23;
screen2.Width = 50;
List<Screen> screens = new List<Screen>();
screens.Add(screen1);
screens.Add(screen2);
Debug.WriteLine(Object.ReferenceEquals(screen1, screens[0])); // outputs true
Debug.WriteLine(Object.ReferenceEquals(screen2, screens[1])); // outputs true
Debug.WriteLine(Object.ReferenceEquals(screen1, screen2)); // outputs false

Can I detect whether I've been given a new object as a parameter?

Short Version
For those who don't have the time to read my reasoning for this question below:
Is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters?
Long Version
There are plenty of methods which take objects as parameters, and it doesn't matter whether the method has the object "all to itself" or not. For instance:
var people = new List<Person>();
Person bob = new Person("Bob");
people.Add(bob);
people.Add(new Person("Larry"));
Here the List<Person>.Add method has taken an "existing" Person (Bob) as well as a "new" Person (Larry), and the list contains both items. Bob can be accessed as either bob or people[0]. Larry can be accessed as people[1] and, if desired, cached and accessed as larry (or whatever) thereafter.
OK, fine. But sometimes a method really shouldn't be passed a new object. Take, for example, Array.Sort<T>. The following doesn't make a whole lot of sense:
Array.Sort<int>(new int[] {5, 6, 3, 7, 2, 1});
All the above code does is take a new array, sort it, and then forget it (as its reference count reaches zero after Array.Sort<int> exits and the sorted array will therefore be garbage collected, if I'm not mistaken). So Array.Sort<T> expects an "existing" array as its argument.
There are conceivably other methods which may expect "new" objects (though I would generally think that to have such an expectation would be a design mistake). An imperfect example would be this:
DataTable firstTable = myDataSet.Tables["FirstTable"];
DataTable secondTable = myDataSet.Tables["SecondTable"];
firstTable.Rows.Add(secondTable.Rows[0]);
As I said, this isn't a great example, since DataRowCollection.Add doesn't actually expect a new DataRow, exactly; but it does expect a DataRow that doesn't already belong to a DataTable. So the last line in the code above won't work; it needs to be:
firstTable.ImportRow(secondTable.Rows[0]);
Anyway, this is a lot of setup for my question, which is: is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters, either in its definition (perhaps by some custom attributes I'm not aware of) or within the method itself (perhaps by reflection, though I'd probably shy away from this even if it were available)?
If not, any interesting ideas as to how to possibly accomplish this would be more than welcome. For instance I suppose if there were some way to get the GC's reference count for a given object, you could tell right away at the start of a method whether you've received a new object or not (assuming you're dealing with reference types, of course--which is the only scenario to which this question is relevant anyway).
EDIT:
The longer version gets longer.
All right, suppose I have some method that I want to optionally accept a TextWriter to output its progress or what-have-you:
static void TryDoSomething(TextWriter output) {
// do something...
if (output != null)
output.WriteLine("Did something...");
// do something else...
if (output != null)
output.WriteLine("Did something else...");
// etc. etc.
if (output != null)
// do I call output.Close() or not?
}
static void TryDoSomething() {
TryDoSomething(null);
}
Now, let's consider two different ways I could call this method:
string path = GetFilePath();
using (StreamWriter writer = new StreamWriter(path)) {
TryDoSomething(writer);
// do more things with writer
}
OR:
TryDoSomething(new StreamWriter(path));
Hmm... it would seem that this poses a problem, doesn't it? I've constructed a StreamWriter, which implements IDisposable, but TryDoSomething isn't going to presume to know whether it has exclusive access to its output argument or not. So the object either gets disposed prematurely (in the first case), or doesn't get disposed at all (in the second case).
I'm not saying this would be a great design, necessarily. Perhaps Josh Stodola is right and this is just a bad idea from the start. Anyway, I asked the question mainly because I was just curious if such a thing were possible. Looks like the answer is: not really.
No, basically.
There's really no difference between:
var x = new ...;
Foo(x);
and
Foo(new ...);
and indeed sometimes you might convert between the two for debugging purposes.
Note that in the DataRow/DataTable example, there's an alternative approach though - that DataRow can know its parent as part of its state. That's not the same thing as being "new" or not - you could have a "detach" operation for example. Defining conditions in terms of the genuine hard-and-fast state of the object makes a lot more sense than woolly terms such as "new".
Yes, there is a way to do this.
Sort of.
If you make your parameter a ref parameter, you'll have to have an existing variable as your argument. You can't do something like this:
DoSomething(ref new Customer());
If you do, you'll get the error "A ref or out argument must be an assignable variable."
Of course, using ref has other implications. However, if you're the one writing the method, you don't need to worry about them. As long as you don't reassign the ref parameter inside the method, it won't make any difference whether you use ref or not.
I'm not saying it's good style, necessarily. You shouldn't use ref or out unless you really, really need to and have no other way to do what you're doing. But using ref will make what you want to do work.
No. And if there is some reason that you need to do this, your code has improper architecture.
Short answer - no there isn't
In the vast majority of cases I usually find that the issues that you've listed above don't really matter all that much. When they do you could overload a method so that you can accept something else as a parameter instead of the object you are worried about sharing.
// For example create a method that allows you to do this:
people.Add("Larry");
// Instead of this:
people.Add(new Person("Larry"));
// The new method might look a little like this:
public void Add(string name)
{
Person person = new Person(name);
this.add(person); // This method could be private if neccessary
}
I can think of a way to do this, but I would definitely not recommend this. Just for argument's sake.
What does it mean for an object to be a "new" object? It means there is only one reference keeping it alive. An "existing" object would have more than one reference to it.
With this in mind, look at the following code:
class Program
{
static void Main(string[] args)
{
object o = new object();
Console.WriteLine(IsExistingObject(o));
Console.WriteLine(IsExistingObject(new object()));
o.ToString(); // Just something to simulate further usage of o. If we didn't do this, in a release build, o would be collected by the GC.Collect call in IsExistingObject. (not in a Debug build)
}
public static bool IsExistingObject(object o)
{
var oRef = new WeakReference(o);
#if DEBUG
o = null; // In Debug, we need to set o to null. This is not necessary in a release build.
#endif
GC.Collect();
GC.WaitForPendingFinalizers();
return oRef.IsAlive;
}
}
This prints True on the first line, False on the second.
But again, please do not use this in your code.
Let me rewrite your question to something shorter.
Is there any way, in my method, which takes an object as an argument, to know if this object will ever be used outside of my method?
And the short answer to that is: No.
Let me venture an opinion at this point: There should not be any such mechanism either.
This would complicate method calls all over the place.
If there was a method where I could, in a method call, tell if the object I'm given would really be used or not, then it's a signal to me, as a developer of that method, to take that into account.
Basically, you'd see this type of code all over the place (hypothetical, since it isn't available/supported:)
if (ReferenceCount(obj) == 1) return; // only reference is the one we have
My opinion is this: If the code that calls your method isn't going to use the object for anything, and there are no side-effects outside of modifying the object, then that code should not exist to begin with.
It's like code that looks like this:
1 + 2;
What does this code do? Well, depending on the C/C++ compiler, it might compile into something that evaluates 1+2. But then what, where is the result stored? Do you use it for anything? No? Then why is that code part of your source code to begin with?
Of course, you could argue that the code is actually a+b;, and the purpose is to ensure that the evaluation of a+b isn't going to throw an exception denoting overflow, but such a case is so diminishingly rare that a special case for it would just mask real problems, and it would be really simple to fix by just assigning it to a temporary variable.
In any case, for any feature in any programming language and/or runtime and/or environment, where a feature isn't available, the reasons for why it isn't available are:
It wasn't designed properly
It wasn't specified properly
It wasn't implemented properly
It wasn't tested properly
It wasn't documented properly
It wasn't prioritized above competing features
All of these are required to get a feature to appear in version X of application Y, be it C# 4.0 or MS Works 7.0.
Nope, there's no way of knowing.
All that gets passed in is the object reference. Whether it is 'newed' in-situ, or is sourced from an array, the method in question has no way of knowing how the parameters being passed in have been instantiated and/or where.
One way to know if an object passed to a function (or a method) has been created right before the call to the function/method is that the object has a property that is initialized with the timestamp passed from a system function; in that way, looking at that property, it would be possible to resolve the problem.
Frankly, I would not use such method because
I don't see any reason why the code should now if the passed parameter is an object right created, or if it has been created in a different moment.
The method I suggest depends from a system function that in some systems could not be present, or that could be less reliable.
With the modern CPUs, which are a way faster than the CPUs used 10 years ago, there could be the problem to use the right value for the threshold value to decide when an object has been freshly created, or not.
The other solution would be to use an object property that is set to a a value from the object creator, and that is set to a different value from all the methods of the object.
In this case the problem would be to forget to add the code to change that property in each method.
Once again I would ask to myself "Is there a really need to do this?".
As a possible partial solution if you only wanted one of an object to be consumed by a method maybe you could look at a Singleton. In this way the method in question could not create another instance if it existed already.

Categories