Let's say you are debugging. At one point you are in Method A, which has a parameter foo of type Foo. Later on you are in Method B, which also takes a parameter foo of type Foo.
These two variables may well be the same Foo instance, but how do you tell? Because they are in different scope, you cannot call ReferenceEquals(). Is there some way you can obtain the actual memory location the variables point to so that you can tell if they are the instance?
I believe you can use the Make Object ID feature. More information on this can be found here, but to summarize:
Set a BreakPoint in your code where you can get to an object variable that is in scope.
Run your code and let it stop at the BreakPoint.
In your Locals or Autos Window, right-click the object variable (note the Value column) and choose "Make Object ID" from the context menu.
You should now see a new ID number (#) new in the Value column.
After you "mark" the object, you will see the assigned ID in the second call to Foo.
While in the debugger, you could store a reference to the object in the first method to a static field and then compare the variable in the second method to the static field.
well you could get a pointer to your variable but this requires to run in an unsafe block.
once you are "unsafed" you can declare a pointer to your Foo like this:
Foo* p = &myFoo;
this has been already discussed here in SO:
C# memory address and variable
As a development of Mark Cidade's suggestion, when inside the first method type the following into the immediate window:
var whatever = foo;
Then, when in the second method, type the following:
bool test = object.ReferenceEquals(whatever, foo);
The immediate window will display the result of the test.
However, CodeNaked's suggestion is better.
Related
Below are the MSDN reference links for the Out keyword and the Ref keyword.
Out Keyword
Ref Keyword
Both Ref and Out keywords are pass by reference, then why it is required for one to be initialized and the other needn't to be initialized? Is it something by design convention or is there any other reason/meaning behind the same? Need some help.
A reference is basically the Address part of:
[Address] => points to => [Object]
The ref keyword passes the address of an existing object. The method can use the object at that address or instantiate an entirely new one (but at the same address). The address does need to be initialized, even if the value it holds is null. (Below is a little test driver that show this).
The out keyword says that the method must instantiate (or set to null) an object (not an address) that it returns.
[TestMethod]
public void TestMethod2()
{
MyClass myClass;
myClass = new MyClass(1);
// Initializing the ADDRESS as an existing object.
ByRefDemo(ref myClass);
Console.WriteLine($"Returned value is: {myClass}");
// Initializing the ADDRESS as a null object.
myClass = null;
ByRefDemo(ref myClass);
Console.WriteLine($"Returned value is: {myClass}");
}
class MyClass
{
public MyClass(int value)
{
Value = value;
}
public int Value { get; }
public override string ToString() => $"{Value}";
}
void ByRefDemo(ref MyClass addressOf)
{
var value = addressOf == null ? "NULL" : $"{addressOf}";
Console.WriteLine($"Incoming value is: {value}" );
addressOf = new MyClass(2);
}
You may be looking at this from the wrong perspective.
ref and out are both modifiers that are used in a function signature declaration, but they aren't really similar otherwise. They shouldn't both do the same thing or have the same requirements.
ref tells the compiler that you want a reference to something that would ordinarily be passed by value. You are passing a live object. Therefore, you have to already have a live object that you want to pass.
out tells the compiler that you want an output variable. It acts precisely as another function return value. Just like the function return value, anything assigned to it before the function is called will be overwritten by the value set in the function. So your output variable may be declared and even initialized or set but its value will be overwritten anyway.
You may use ref to do something similar to out, which may be dangerous and may violate best practices or other standards that you're using (it does commonly). Using out instead of ref won't work though.
There will be occasions when you're programming, that you aren't programming for yourself; you're programming for the benefit of someone else. Imagine you're writing some awesome parsing library or something..
There aren't any surprises for someone calling your method if they're passing you some reference type by value semantics; C# makes sure your method gets a copy of their reference. You can modify the contents of the instance at end of the reference, sure, but you can't surprise the caller by swapping out the reference they gave you for something else
It's different with things passed by original reference; they could give you some carefully crafted object that took hours to make and you could trash it by setting the reference to null. It would be nice for them to know this ahead of time, so they could keep their own copy of the reference
As such, with your arguments that are passed by original reference rather than by copy, you have 3 choices with which to decorate them to help indicate your intentions towards their data:
out - "don't bother spending hours crafting the perfect object; I will overwrite the reference you give"
ref - "give me some data, but don't be surprised if I replace your object with another. Keep your own reference if you're precious about losing it"
in - "the pass will be done by original reference but I promise I won't swap it out for something else"
The compiler helps you make the first and last promise by insisting that you do set an out/don't set an in; and this is essentially the answer to your question: in/out/ref behave the way they do by design to help you make the promises you make when you use one of them on an argument
out and ref perhaps don't seem to have much of a point if you're looking at things from "I'm going to write this method here and use it there" but it does help describe to someone else (who cannot see the inner workings of what your method does) what you will do with their thing they provide, and that's quite important but easy to overlook if you you don't have that "external caller" perspective in mind
I can't understand this in C#, despite looking for similar questions and answers.
I have an object cCar (class Car) with ID = 0. I passed this object to a method called CreateCarInDB from my class CarManager without using the ref word :
public static void CreateCarInDB(Car p_cCar)
{
int newId = CarDB.SaveNewCar(p_cCar);
p_cCar.ID = new Id;
}
I just want to understand why after executing the method, if i look, the cCar object has its Id = 1 for example. Shouldn't I use the word ref before method parameter so that this value is affected outside the method? I thought I was only passing the value and not the reference.
It doesn't seem I need to use the word ref.
Shouldn't I use the word ref before method parameter so that this value is affected outside the method?
No, because you're not changing the value of p_cCar, which is just a reference. You're changing the content of the object that the reference refers to.
If you had a line of code like this:
p_cCar = new Car();
... and you expected the caller to see that change, then you'd need the ref (or out) keyword. That's rarely what you want to do though, in my experience.
To put it in a real-world way, someone can write their address on a piece of paper and ask you to paint their front door green. You can modify the appearance of their house (painting the front door) and they'll see that. But if you decide to cross out their address on the piece of paper and write a different one, that won't change their idea of where they live.
Further information:
My article on parameter passing
My article on value types and reference types
What's the difference between an object, a reference and a variable?
Just to understand what's gone under the hood for reference types and based on article from Eric Lippert http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx I would like to understand in depth why this code is working like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
MyCalleeClass calleeClass = new MyCalleeClass();
calleeClass.MyTestProp = "toto";
MyCallerClass callerClass = new MyCallerClass();
callerClass.TestMethod(calleeClass);
//normally given that a class it's a reference type this should give a toto 1
Console.WriteLine(calleeClass.MyTestProp);
}
}
class MyCalleeClass
{
public string MyTestProp { get; set; }
}
class MyCallerClass
{
public void TestMethod(MyCalleeClass calleeClass)
{
Console.WriteLine("In the caller method");
//does this object is created on the stack or on the heap
calleeClass = new MyCalleeClass();
calleeClass.MyTestProp = "toto 1";
Console.WriteLine(calleeClass.MyTestProp);
}
}
}
another question if the caleeClass in the testMethod is not created on the stack is there a partiular case where a reference type could be created on the stack
The fact that something is an "implementation detail" means that the actual implementation is not something you should need to know.
So let's deal with the details first:
When you construct an object of a reference type, that object lives on the heap
The reference, however, can live a lot of places:
As a temporary element on the stack
As a variable on the stack
As a field of a value type (and not it lives wherever the value type lives)
As a field of a reference type (and since the reference type lives on the heap, the fields inside it does too)
But this question actually seems to confuse the following two concepts:
Passing a reference type parameter
Passing a parameter by reference
These are two different things, and in the case of your question, the correct statement would be that you're passing a reference type parameter by value.
This all starts to get confusing for a lot of people so let's try to look at what is happening here.
In reality, a reference is just a number. It's something that refers to an object somewhere else in memory. Most likely the number is the address (in memory) of that object.
So, after you've constructed the first object here:
MyCalleeClass calleeClass = new MyCalleeClass();
calleeClass.MyTestProp = "toto";
let's say that calleeClass contains the number (reference) 1234. At address 1234 there lives an object of type MyCalleeClass, and the MyTestProp property of that object has the value "toto".
Ok, then you pass this reference to that method. Basically, you give that method a copy of the reference 1234.
Inside that method you construct another object and assign the reference to this object to the same local variable (the parameter), overwriting the 1234 reference with, say, 5678. Pointing to your new object.
And now you change the property of that object, the new one.
Then you return back to the outer code. Since that code gave the method a copy of the reference 1234, its reference still has 1234 and points to the original object, with "toto" in the property.
This is what it means to pass a reference by value, you give the method a copy of the reference value. The code that is calling still has the original reference.
If you want the code that is calling to continue using the new reference you need to pass the reference by reference. This is also confusing because the two "reference" words here actually mean different things.
A reference is a reference to an object
Passing by reference means to pass access to the underlying variable, and not just a copy of its value
TL;DR Your code behaves the way it does because you're using one object on the outside, and construct and change a new object on the inside, but the outside world does not get back that new object and continues to use the old one.
As for your second question, can a reference type be allocated on the stack, then no. All objects are allocated on the managed heap.
You can allocate something which looks like a reference type on the stack, arrays of primitives/value types, in unsafe code, like this:
unsafe void Test()
{
int* values = stackalloc int[10];
}
But this isn't an "array reference type", it's just a pointer to the first of 10 int values allocated on the stack, so it's not the same thing.
This can turn into a large discussion.
In your TestMethod the MyCalleeClass is generated.
Since this is a class(ref. type) then it's generated on the heap(lets say at address 1000).
Your stack will contain a pointer to address 1000.
At address 1000 you will have another reference to the string you have in your class(a string is also a ref. type that will sit in address 2000 - for this example).
So:
TestMethod's stack will have a pointer to address 1000.
In address 1000 you will have a pointer to address 2000.
In address 2000 you will have a string.
In your main:
callerClass.TestMethod(calleeClass) -> the reference to the calleeClass is copied as an argument
in your TestMethod
calleeClass = new MyCalleeClass -> the copied reference (argument of the method) is overwritten to reference another object
when the TestMethod call is returned, the reference is not copied back, so you are still referencing the original class in your main.
If you do want the behaviour you suggest, you should specify: TestMethod(ref MyCalleeClass calleeClass).
I learnt the reference type parameter passing is just a copy of the reference. If you set the passed in refernece parameter point to another object inside the called method, the orginal reference will not change.
I have a test method to test the reference type parameter passing. A refTest(SystemSwEvent systemSwEvent) method is called from that test method with a valid SystemSwEvent type object. Inside the refTest() method, the processEvScanDataAvailable(EvScanDataAvaialble systemSwEvent) method is called. Inside the processEvScanDataAvailable(EvScanDataAvaialble systemSwEvent) method, I set the passed in reference parameter to null. I expect the parameter in refTest() should not be changed. But that is not true. It will be changed to null momentarily. why?
The debugger recognizes the name in the current context and shows the value. It's just a coincidence that you pointed your cursor at a place that actually triggered the currently executing method (the current context).
Also note you can use the Call Stack tool to inspect the parameters of caller methods.
why?
I suspect this is a debugger issue, and not representative of what's actually occurring inside the CLR.
Try using different variable names for your arguments, and this behavior will go away.
Object references are by default (if you don't qualify them with ref or out) passed by value, so the method is receiving a copy of the object reference - setting that copy to null doesn't change the original object reference, so what you claim to see is impossible and most likely you are just misinterpreting what you see in the debugger.
The debugger is getting confused because your parameter and variable have the same name. If you change the name of your parameter, you will notice that that debugger no longer gives information about the variable being passed into the method, but only gives information on the variable inside the method.
Simply change the name of that parameter, and you will no longer have this issue.
I have the following line of code:
var dmrReceived = new DownloadMessagesReport();
StyleCop and ReSharper are suggesting I remove the redundant initializer. However if I replace it with
DownloadMessagesReport dmrReceived;
surely this will generate an object reference not set to an instance of an object? I am using .NET 3.5. Do you no longer manually have to instantiate objects?
Next line that follows is:
dmrReceived = dc.DownloadNewMessages(param, param2, param3);
It's worth noting that dc is a class generated from a WCF service. So DownloadNewMessages is a WCF web service method.
If it's a field, it will be automatically initialised to its default value - null for a reference type. Given the var however, I'm guessing it's not, and that you're actually instantiating it further down in your code anyway, thereby discarding the value you have instantiated here. You don't need to initialise a variable where it's declared. If you want to use var you do, but then I'd recommend you declare it where you actually first use it.
So your code is
var dmrReceived = new DownloadMessagesReport();
dmrReceived = dc.DownloadNewMessages(param, param2, param3);
The second line does not fill the object you created in the first line but it completely replaces that object. So the first assignment is not needed (as the first object is never used), which is what R# is warning about.
That will only generate an object reference error if dmrReceived is accessed before it is assigned. A lot of the times, the reason for resharper saying that an initializer is redundant is that the variable will always be assigned another value in every single possible execution path.
i.e.
DownloadMessagesReport dmrReceived;
...
if(condition) {
dmrReceived = new DownloadMessagesReport();
} else {
throw new Exception("oh no");
}
return dmrReceived.SomeProperty;
Accessing SomeProperty is the first place in the code where dmrReceived actually needs to have a value. As follows from the rest of the code, there's no way to get to that line of code without assigning it a value, therefore, the initial value that might have been assigned, would not be used in any execution path, and would thus be redundant.
"Do you no longer manually have to
instantiate objects?"
Of course you need to "manually" instantiate objects, how would the compiler know when or where to instantiate it otherwise?
A simple scenario is this:
MyType x;
if ( EverythingWorkedOut )
x = new MyType(params);
else
x = null;
If the compiler instantiated it the first time, it would be redundant and more overhead in all code.
Don't trust ReSharper or any other Computer-Intelligent-Stuff over your own Instincts! They're not always right you know.
Just a side note, you don't really need to do x = null; since it should be the default value of a non-instantiated object.
Supposing this is your code:
var dmrReceived = new DownloadMessagesReport();
dmrReceived = dc.DownloadNewMessages(param, param2, param3);
You are creating an instance of a DownloadMessagesReport in the first line. And then you throw this object away by assigning the dmrReceived variable another value returned from DownloadNewMessages method. The first new DownloadMessagesReport() object is redundant. You effectively creating garbage that Garbage Collector will have to clean at some point.
That's why ReSharper and StyleCop showing you warning.
If you can initialize variable with actual value right in the same line where the variable is declared then do it.
Surely this is enough?
DownloadMessagesReport dmrReceived = dc.DownloadNewMessages(param, param2, param3);