C# Is this initialiser really redundant? - c#

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);

Related

Why ref keyword needs to be initialized and out keyword needn't to be initialized before it is it passed?

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

Out parameter might not be initialized before accessing

Why is the code below
private static List<WorkflowVariableDataSet> MergeDatasetsListBranch(out List<WorkflowVariableDataSet> datasetsList)
{
if(datasetsList == null)
datasetsList=new List<WorkflowVariableDataSet>();
datasetsList=new List<WorkflowVariableDataSet>();
return datasetsList;
}
generating an error at the first if statement:
Out parameter 'datasetsList' might not be initialized before accessing.
I know it should be uninitialized at this point, but the word might suggest that the error lies in possible uninitialized object accessing (when it's not even accessed, it's the reference, that is checked). Ofc that doesn't happen with ref keyword, but I'm curious how is the reference checking violating out-parameters policy.
EDIT
I've edited the question and the example: the out object will be initialized inside the method anyway. The question is: WHY uninitialized object cannot be null compared? How is that different from:
object o;
if(o==null)
...
Compiler Error CS0269
Use of unassigned out parameter 'parameter' The compiler could not
verify that the out parameter was assigned a value before it was used;
its value may be undefined when assigned. Be sure to assign a value to
out parameters in the called method before accessing the value. If you
need to use the value of the variable passed in, use a ref parameter
instead.
So treat an out-parameter as unassigned. You are the one who is responsible.
So just remove the if:
datasetsList = new List<WorkflowVariableDataSet>();
If you want to process a list that is passed to this method use ref intead (as suggested above):
Because whether you've buggy code that never initialises the parameter, or buggy code that sometimes doesn't initialise it, it's still the same bug.
There's no point having a separate error message for the same bug depending on whether it hits in all or just one code paths; if there is a single code-path where the parameter is used before initialising, then it's has that error, and if there isn't a single code-path, then it doesn't.
So if we consider:
private static List<WorkflowVariableDataSet> MergeDatasetsListBranch(out List<WorkflowVariableDataSet> datasetsList)
{
if(_someBooleanField)
datasetsList = null;
if(datasetsList == null)
datasetsList=new List<WorkflowVariableDataSet>();
return datasetsList;
}
Here the use of an uninitialised out parameter might or might not happen, but that suffices to mean it has the same error.
As far as the error goes, there really isn't any significant difference between these two cases.
And therefore the error message uses might, even in cases where it will always apply.
Out arguments need not be initialized prior to being passed, the calling method is required to assign a value before the method returns.
Modified your code
private static List<WorkflowVariableDataSet> MergeDatasetsListBranch(out List<WorkflowVariableDataSet> datasetsList)
{
return datasetsList = new List<WorkflowVariableDataSet>();
}

What happens behind the scenes when a value is set to null?

Lets say I have a populated array of objects.
Resource[] list = new Resource[100000];
And once in a while, I would like to change an object in this list to a default value.
Resource defaultResource = new Resource();
And later on, I would like to check if the item is default or not.
So, I am wondering what the performance differences might be in setting the list object to a default value, versus setting a value to null.
list[i] = defaultResource; /*versus*/ list[i] = null;
So really, I would like to know what goes on behind the scenes when a value is set to null versus setting it equal to something else.
Sorry if this is a dumb question!
There's not much difference between setting a variable to an existing object vs. setting it to null. In both cases, the object that has been referenced by that variable before would get one step closer to becoming eligible for garbage collection, regardless of the new value stored in that variable being a null or a different object. The rest of the assignment goes in the same way, too: CLR does not maintain reference count, so nothing special needs to happen specifically at the point when the assignment is made.
It may be beneficial to store a default object in place of a null to avoid extensive null checking at runtime, though: doing so simplifies the code, and reduces the need for branching at runtime.
One possible option to consider for your scenario - you want the simplification of not having to write null checking code.
Consider subclassing your Resource class with a stub that represents a default value.
public class NoResource : Resource { }
// ... later
if (res is NoResource) {
// handle default value
}
This way, your code is still able to work with Resource objects as it expects to be able to, and you can optionally check for a default Resource easily.

How to determine reference equality of two variables in different scope?

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.

c# - ref modifier for ...reference types

I am a bit confused about this piece of code.
public static void Foo(A p)
{
p.SomeProp = "ccc";
p = null; // !!!
}
static void Main(string[] args)
{
A p = new A();
Foo(p);
Console.WriteLine("SomeProp is: " + p.SomeProp);
Console.ReadLine();
}
The output is:
"SomeProp is: ccc"
But I would have expected a NullReferenceException.
However, if I change it like so, using the ref modifier:
public static void Foo(ref A p)
{
p.SomeProp = "ccc";
p = null;
}
static void Main(string[] args)
{
A p = new A();
Foo(ref p);
Console.WriteLine("SomeProp is: " + p.SomeProp);
Console.ReadLine();
}
I get a NullReferenceException - the second one is understandable for me.
But how can it be, that in the first piece of code p is NOT set to null, but the property gets its value set?
My question is: what is the p argument of the Foo method in the first piece of code if it is not a reference to the orginal instance?
Btw. here is the definition of class A
public class A
{
public string SomeProp;
}
In .Net, everything is passed by value unless you explicitly use the ref or out keywords. For reference types, that means passing a copy of the reference.
In your first example, that means your p variable is still a reference to the same object, and so setting a property works like you would expect. But when you set the reference itself to null, all you changed was the copy.
p.SomeValue = "ccc";
is saying:
Get the object that p is a reference to
Set the value of the property SomeValue on that object to "ccc"
p = null;
is saying:
Change p to, instead of referring to the object it used to, now refer to null.
It is not saying change the object that p refers to to null, but that the local variable p should now refer to null.
By default, when you pass an argument of type A such as in the method invocation "Foo(p)" you are not passing the object that is referenced by p, or even the reference p, but a reference to the object referenced by p. They reference the same object, but they are not the same reference. i.e. the reference p in "public static void Foo(A p)" is not the same reference as the p in "Foo(p)", but they do reference the same object.
You can alter this behaviour by using a ref parameter instead. This changes it so that they are the same reference, and altering the value of one alters the value of the other.
Object references are passed by value. <-- Very important.
Your method has a copy of the reference so, when you say p = null, you are only changing the copy of that reference. When you return, the original reference 'p' still has it's original value.
In the second example, you pass your object by reference explicitly. So, the new reference (null) is passed back to your calling function (which then gives you the null exception).
The p argument is a copy of the reference to the new Foo instance you made. Think about it as a signpost: calling "new A()" creates a A object on the heap, and gives you back a signpost to it, that you store in p. You then call the Foo function, and give it a copy of the signpost - it knows how to get to the A object, and updates the property. It then scribble all over the signpost - it can't get there any more, but the object still exists. The caller still has a valid signpost, so no exception is thrown.
The second instance, with the "ref" parameter effectively says "Don't give me a copy of the signpost, give me the actual signpost". This time, when it scribbles all over it, the original that was passed to the function is lost as well, and the exception occurs.
In more technical terms, C# is, without the ref keyword, always "Call by value" - all parameters are passed copies of the value of the argument. The fact that the value of the argument is a signpost (or "reference"), doesn't matter.
Here's an article with a graphical representation of what you're seeing:
Parameter passing in C# (Lee Richardson)
I found this article really helpful.
And I'm surprised nobody's linked Jon Skeet's article (from which I found the link above):
Parameter passing in C# (Jon Skeet's blog)
In the first function, you are only setting the local reference to p to null. You are not setting the p in main to null. In the second function, by virtue of the use of ref, you are setting the p in main to null.
C# uses pass by value unless you use out/ref. When you pass the reference by value. The reference is copied. However, since it still refers to the same object on the heap, you can modify the state of the object via the reference. If you use ref your passing the address of the reference. Nulling this reference nulls the actual reference and hence the NullReferenceException when you access the original reference after that.
How is it though that if you add "p" to the watch list while debugging and generate an object id for it, that id is the same as the id of "p" inside the function Foo(p). So essentially both "p" in the calling method and "p" in Foo have the same object id.
When you pass an object reference by valule you can change its states. But when you pass an object reference by reference you can not only change its states but actual object itself.
Edited: After knowing objects are never passed as value or reference but a reference to an object is passed as value or reference.

Categories

Resources