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.
Is there like a rule of thumb about when to go either over the other?
Im curious because i have a dilemma here, where i have a very frequently used method, return a custom class type that is rather large. Im wondering if it wouldnt be cheaper to hold an instance of this custom class in a field, and then in the method just change and return it every time, rather than creating a whole new object as would be the case if i had a new class instance created in the method every time.
The main difference between returning a newly created instance of a class and returning a field is enormous: in the latter case, the instance is shared because all clients receive a pointer to the same instance. That means: whenever any of the clients (or the original creator of the instance) changes something in the instance, all clients will now see all those changes. In the former case, all instances are different, and changes affect only the current client.
So take a really close look at the requirements and find out which of the behaviors is required. Getting them wrong can have devastating effects.
What you seem to ask for is a so called lazy field. You declare it as System.Lazy<> like so
private System.Lazy<YourClass> mYourClassInstance;
...
mYourClassInstance = new System.Lazy<YourClass>(() => new YourClass());
and then you can get the instance via
mYourClassInstance.Value
anywhere you want but the value (instance) is only created once.
I have a little problem when i want to do some operations in c#. I will give you a little example.
Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>();
List<HufmannLetter> letterList = new List<HufmannLetter>();
while(true){
letterList.Add("asd");
letterList.Add("sad");
steps.Push(letterList);
letterlist.Clear();
}
In this code, I want to push my linkedlist to a stack than remove all the items in the list. When I clear the list, my stack's first index disappears because it passed by reference. Am i wrong? Because I dont know why it happens.
So I use pass by value method.
Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>();
List<HufmannLetter> letterList = new List<HufmannLetter>();
while(true) {
letterList.Add("asd");
letterList.Add("sad");
List<HufmannLetter> tempLetterList = new List<HufmannLetter>(letterList);
steps.Push(tempLetterList);
letterlist.Clear();
}
Is it a good way to solve a problem? This way it is working, but readability decreases. What do you suggest me?
Thanks...
Just create a new List<HufmannLetter> object inside the loop and add that to the stack. Reusing the same list object won't have any performance benefits.
Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>();
while(true)
{
List<HufmannLetter> letterList = new List<HufmannLetter>();
letterList.Add("asd");
letterList.Add("sad");
steps.push(letterList);
}
You can create new List<HufmannLetter>() and give in the constructor the previous list, this will create new object which will be not cleared.
while(condition)
{
letterList.Add("asd");
letterList.Add("sad");
steps.push(new List<HufmannLetter>(letterList));
letterlist.Clear();
}
EDIT
So List<T> is reference type, you are putting the letterList in the stack. In this way you are transferring the value of the reference List<T> in the stack item. So your letterList variable reference the same object as the item in your stack. When you clear the items from letterList, they are cleared in the item of the stack too.
Check what is Reference Types
List<> is a mutable reference type.
When you pass a List<> to a method, you pass a copy of the reference. So you just tell which List<> it is. That will not copy (clone) the entire contents of the List<>.
When you put (Push) a List<> on the Stack<>, what the Stack<> really keeps is a copy of a reference to this instance of List<>. If that instance is later modified, for example with .Add("asd") or with .Clear(), this "mutation" will be seen whether you follow the reference kept by the Stack<> or another reference you have, from the local variable. Both references "point" to the same instance of List<>.
When, in your code, you say:
letterList.Clear(); // do not change reference, follow reference and mutate the instance it refers to
that will modify (mutate) the existing instance of List<> so it becomes empty. This change will be seen by anyone holding a reference to this particular instance of List<>.
If instead you had done:
letterList = new List<string>(); // create new instance, change reference to point there (reference assignment), old instance is unchanged
that would have "moved" the reference of letterList to point to a new instance of List<>. This would not affect people with other references to the "old" instance.
The title Pass By Reference Usage is misleading. It should have been Reference Types And Passing References or something like that.
you can also do that as
Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>();
while(true)
{
var tempList = new List<HufmannLetter>;
tempList.add("asd");
steps.push(tempList);
}
or you can try this
steps.push(tempList.ToList());
tempList.Clear();
MyRequest copyRequest = new MyRequest();
copyRequest = request;
copyRequest.MyList.Clear();
I have above codes
MyList is a list of strings
When I call copyRequest.MyList.Clear()
it also clears request.MyList.
Is there any way to clear only copyRequest.MyList
This code:
MyRequest copyRequest = new MyRequest();
copyRequest = request;
...does not create a copy of request. It just reassigns the reference of request so it is one object with 2 aliases and the instance created with the new operator will be GCd as it has no references.
You need to implement IClonable which will then be responsible for creating a deep-copy of your MyRequest object, including the items of MyList.
By assigning the request to copyRequest both variables refer to the same objects. So if you then clear the list that affects to all variables referencing this object.
You have to create a new MyRequest and assign all related objects from the original request to the "copied". I assume the list is empty by default, so you don't need to assign and clear it.
MyRequest copyRequest = new MyRequest();
copyRequest.Property1 = request.Property1;
copyRequest.Property2 = request.Property2;
copyRequest.Property3 = request.Property3;
Since J. Skeet explains much better the difference of references and variables here's a quote:
One analogy I often use is of a house. Suppose we have two pieces of
paper (variables). The same house address is written on both pieces of
paper (that's the value of each variable, the reference). There's only
one house. If someone uses the first piece of paper to get to the
house, then paints the door red, they're not changing anything about
their piece of paper - they're changing something about the house.
Then if someone uses the second piece of paper to get to the house,
they'll see the front door is red too. There's only one house, however
many pieces of paper have its address written on them.
More detailed: http://jonskeet.uk/csharp/references.html
As others have pointed out, you're copying a reference, not the contents of MyList.
It's not clear what you're trying to achieve in the code, but it looks like what you want is a new MyRequest that is identical to the original except for the MyList, which you want to be emtpy. What you might want to do then is create a method that produces a new MyRequest without an empty MyList.
Bear in mind, though, that any reference in MyRequest will behave much the same way as MyList does. I.e., if Property1 is a reference type, the following
myResultCopy.Property1 = myResultOriginal.Property1
will result in myResultCopy.Property1 and myResultOriginal.Property1 referring to the same instance. So any change to myResultCopy.Property1 will be seen by users of myResultOriginal.Property1.
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.