I am using the FileHelpers nuget to read the files. It works as excepted but it throws me a warning when I tried to debug in Visual Studio.
How to get rid of warning CS0649: Field 'Orders.Freight' is never assigned to, and will always have its default value null ?
class Orders : INotifyRead
{
[FieldFixedLength(10)]
public string Freight;
public void BeforeRead(BeforeReadEventArgs e)
{
if (e.RecordLine.StartsWith("Machine"))
// ||
// e.RecordLine.StartsWith("-"))
e.SkipThisRecord = true;
}
public void AfterRead(AfterReadEventArgs e)
{
// we want to drop all records with no freight
if (Freight == "_raw")
e.SkipThisRecord = true;
}
}
No, do not explicitly assign a default value to Freight.
The warning is legitimate, because you never really assign a value to the field.
You do not assign a value, because the field gets populated by magic. (Incidentally, that's why I do not like magic; but that's a different story altogether.)
So, the best approach is to acknowledge the fact that the warning is legitimate but accounted for, and to explicitly suppress it.
So, take a look at the documentation of the #pragma warn directive:
https://msdn.microsoft.com/en-us/library/441722ys.aspx
For the sake of completeness, I'm just going to combine blins' answer and Mike's answer - nothing original, just trying to help the next person who runs across this page.
Per blins: You may set the value equal to null and the first warning "Field XYZ is assigned to but never used"
public string Freight = null; //or = "", or = default(string) (which is null)
Per Mike, the "magic" he's talking about is Reflection. The variable is assigned to at runtime. This is something the compiler doesn't detect. More on Mike's answer about suppressing the warning found here: Suppressing "is never used" and "is never assigned to" warnings in C#
To suppress warnings for "Field XYZ is never used", you do this:
#pragma warning disable 0169
... field declaration
#pragma warning restore 0169
To suppress warnings for "Field XYZ is never assigned to, and will always have its default value XX", you do this:
#pragma warning disable 0649
... field declaration
#pragma warning restore 0649
You essentially have two choices and which way to go really depends on the intent (to suggest one or the other is subjective). First, you could eliminate the warning if the design requirement of your Orders type dictates that it should have a null default value.
public string Freight = null;
The above merely clarifies that intent and therefore eliminates the warning.
The alternative is to suppress the warning as the other answers mention. In your case, if the assumption is that the value should have been set via Reflection then this alternative seems reasonable if not preferable in such a case.
Related
I'm writing on a script for Unity 3D and have/want to use some pre-processors.
For example VisualStudio always throughs some warnings such as
Field 'foo' is never assigned to, and will always have its default
value 'null' (CS0649) (Assembly-CSharp)
for a code like
puclic class Example : MonoBehvaiour
{
[SerializedField]
private GameObject exampleObject;
...
}
though the field ofcourse will be set within the Inspector of the Unity Editor.
Additionally I never use the field in this class but have written a CustomEditor where the field is needed. So I also would get some other warnings something like
variable declared but not used.
variable assigned but not used.
private field assigned but not used.
So after making sure that the code is correct and those warnings unneccesary I decided to follow this and this post and used some pre-processors e.g.
#pragma warning disable 0414
#pragma warning disable 0649
// some fields here
#pragma warning restore 0414
#pragma warning restore 0649
So now to my question:
And how could I add comments for pre-processors?
It's a pity there is not just something like
#comment "some comment here"
This seems not really intended/thought about but I would really like to do it in order to let my collegues know what the pre-processors are good/used for.
Ofcourse I could just add the comments but they are not intended with the pre-processors but with the normal code as e.g.
// This silences "private field assigned but not used." warnings
#pragma warning disable 0414
// flag to look for unsaved changes
private bool _unsavedChanges = false;
// This re-enables "private field assigned but not used" warnings
#pragma warning restore 0414
this makes it look very cluttered instead of clarify things and the comments don't seem to refer/"belong" to the pre-processors but the normal code instead.
The alternative would be inline comments which for now come closest to it I guess
#pragma warning disable 0414 // This silences "private field assigned but not used." warnings
// flag to look for unsaved changes
private bool _unsavedChanges = false;
#pragma warning restore 0414 // This re-enables "private field assigned but not used" warnings
Note:
I do not want to just disable warnings in general for the file or project!
And these examples are not the only pre-processors I'ld like to add comments for.
public class Program
{
public static void main(String[] args)
{
string message = "This is a message";
int number = 6;
object obj = null;
int? nullable = (int?)12;
}
}
The first three variable declarations on this program throw the following warning:
The variable 'X' is assigned but its value is never used
Yet, the last statement:
int? nullable = (int?)12;
doesn't throw anything. Why is that?
The warning that you're seeing is only shown in cases where the compiler can prove that the expression used to initialize the variable can't possibly cause any side effects. When you're just assigning a literal string, integer, or null value to a variable, the compiler knows that none of those things can possibly cause side effects. For your last value you're not just assigning a literal value though; you're using the explicit operator of a type as well, and as far as the compiler is concerned, that operator is just some code that could do anything. It could, for example, cause relevant side effects (it doesn't, but the compiler doesn't know that) that would make the line not superfluous.
Warnings are best practice suggestions, they are not true errors. Visual studio is smart enough to see you created the variables but never used them so they are useless. It is recommending that you get rid of them since you don't use them.
If you actually do something with them then the errors will go away. For example if you said:
number += nullable;
Would get rid of 1 of the errors. If you did something like:
message = message + " and this is more message";
It would get rid of the other error.
I believe it sees the int? as an object and since you are casting it to the nullable variable, it can't figure out if it had been used before hand. I think it has something more to do with the casting just isn't caught as an error because it can't tell if you referenced that variable somewhere else.
I think it would be the equivalent of something like this:
var a = new SomeClass();
var b = a;
Since it can't tell if a has really been used, then it doesn't show an error. If you put that in with a real class it will not show the error also.
It seems like the Warning doesn't show because the line with the nullable actually do an operation before the assignation. As for exemple the following code only generate a warning on the variable named number. This seems to be logical in the meaning that the line with warning are truely useless in the current code. The other lines might do something during the execution and will not be "optimized out". To test it run your code in release mode with the debugger ad you will see that all lines that have a warning are skipped ("optimized")
class Program
{
static void Main(string[] args)
{
string message = ';'.ToString();
int number = 6;
object obj = (object)(new t());
int? nullable = (int?)12;
}
class t
{ }
}
With this being said. The nullable it not optimized because there is a cast from a int '12' to a int?. Since it is a real cast and not a "useless cast" an operation is needed during the run time.
I have the following code:
ViewPortViewModel _Trochoid;
public ViewPortViewModel Trochoid
{
get { return _Trochoid; }
set { this.RaiseAndSetIfChanged(value); }
}
using ReactiveUI INPC support. The compiler is always warning me that Trochoid is never assigned to and will always be null. However due to the magic that RaiseAndSetIfChanged performs through CallerMemberName support, the code does work and the compiler is wrong.
How do I cleanly suppress these warnings in my code?
How to cleanly suppress these warnings in my code
An alternative to an inappropriate assignment would be to just a #pragma:
#pragma warning disable 0649 // Assigned by reflection
ViewPortViewModel _Trochoid;
#pragma warning restore 0649
That should work, and it keeps the ugliness at exactly the place that it makes sense to document it - at the field declaration.
If you have multiple fields handled in the same way, you could put them all in the same "block" of disabled warnings, with a comment applicable to all of them.
Whether you view this as "clean" or not is a matter of taste, of course. I think I prefer it to assignments which are only there for the side-effect of removing the warnings.
Now that every platform has CallerMemberNameAttribute support in ReactiveUI, there's no need to suffer the oppression of your Obsessive Compulsive Compiler:
ViewPortViewModel _Trochoid;
public ViewPortViewModel Trochoid
{
get { return _Trochoid; }
set { this.RaiseAndSetIfChanged(ref _Trochoid, value); }
}
The other overloads are really unnecessary now, but I leave them in because removing them is a breaking change and therefore won't be done until ReactiveUI 5.0
You could assign it a default for a reference type:
ViewPortViewModel _Trochoid = null;
I have a HTTPSystemDefinitions.cs file in C# project which basically describes the older windows ISAPI for consumption by managed code.
This includes the complete set of Structures relevant to the ISAPI not all or which are consumed by code. On compilation all the field members of these structures are causing a warning like the following:-
Warning Field 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' is never assigned to, and will always have its default value null
or
Warning The field 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' is never used
Can these be disabled with #pragma warning disable? If so what would the corresponding error numbers be? If not is there anything else I can do? Bear in mind that I only what to do this for this file, its important that I get see warnings like these coming from other files.
Edit
Example struct:-
struct HTTP_FILTER_PREPROC_HEADERS
{
//
// For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
// Header names should include the trailing ':'. The special values
// 'method', 'url' and 'version' can be used to retrieve the individual
// portions of the request line
//
internal GetHeaderDelegate GetHeader;
internal SetHeaderDelegate SetHeader;
internal AddHeaderDelegate AddHeader;
UInt32 HttpStatus; // New in 4.0, status for SEND_RESPONSE
UInt32 dwReserved; // New in 4.0
}
Yes, these can be suppressed.
Normally, I'm opposed to suppressing warnings, but in this case, structs used for interop absolutely requires some fields to be present, even though you never intend to (or can) use them, so in this case I think it should be justified.
Normally, to suppress those two warnings, you would fix the offending code. The first ("... is never used") is usually a code-smell of leftovers from earlier versions of the code. Perhaps code was deleted, but fields left behind.
The second is usually a code-smell for incorrectly used fields. For instance, you might incorrectly write the new value of a property back to the property itself, never writing to the backing field.
To suppress warnings for "Field XYZ is never used", you do this:
#pragma warning disable 0169
... field declaration
#pragma warning restore 0169
To suppress warnings for "Field XYZ is never assigned to, and will always have its default value XX", you do this:
#pragma warning disable 0649
... field declaration
#pragma warning restore 0649
To find such warning numbers yourself (ie. how did I know to use 0169 and 0649), you do this:
Compile the code as normal, this will add some warnings to your error list in Visual Studio
Switch to the Output window, and the Build output, and hunt for the same warnings
Copy the 4-digit warning code from the relevant message, which should look like this:
C:\Dev\VS.NET\ConsoleApplication19\ConsoleApplication19\Program.cs(10,28):
warning CS0649: Field 'ConsoleApplication19.Program.dwReserved' is never
assigned to, and will always have its default value 0
Caveat: As per the comment by #Jon Hanna, perhaps a few warnings is in order for this, for future finders of this question and answer.
First, and foremost, the act of suppressing a warning is akin to swallowing pills for headache. Sure, it might be the right thing to do sometimes, but it's not a catch-all solution. Sometimes, a headache is a real symptom that you shouldn't mask, same with warnings. It is always best to try to treat the warnings by fixing their cause, instead of just blindly removing them from the build output.
Having said that, if you need to suppress a warning, follow the pattern I laid out above. The first code line, #pragma warning disable XYZK, disables the warning for the rest of that file, or at least until a corresponding #pragma warning restore XYZK is found. Minimize the number of lines you disable these warnings on. The pattern above disables the warning for just one line.
Also, as Jon mentions, a comment as to why you're doing this is a good idea. Disabling a warning is definitely a code-smell when done without cause, and a comment will prevent future maintainers from spending time either wondering why you did it, or even by removing it and trying to fix the warnings.
Another "solution" to fix these warnings is by making the struct public. The warnings are not issued then because the compiler can't know whether or not the fields are being used (assigned) outside of the assembly.
That said, "interop" components should usually not be public, but rather internal or private.
I got VS to generate the implementation skeleton for System.ComponentModel.INotifyPropertyChanged and the events were implemented as fields which triggered the CS0067 warnings.
As an alternative to the solution given in the accepted answer I converted the fields into properties and the warning disappeared.
This makes sense since the property declarations syntax sugar are compiled into a field plus getter and/or setter methods (add/remove in my case) which reference the field. This satisfies the compiler and the warnings are not raised:
struct HTTP_FILTER_PREPROC_HEADERS
{
//
// For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
// Header names should include the trailing ':'. The special values
// 'method', 'url' and 'version' can be used to retrieve the individual
// portions of the request line
//
internal GetHeaderDelegate GetHeader {get;set;}
internal SetHeaderDelegate SetHeader { get; set; }
internal AddHeaderDelegate AddHeader { get; set; }
UInt32 HttpStatus { get; set; } // New in 4.0, status for SEND_RESPONSE
UInt32 dwReserved { get; set; } // New in 4.0
}
C/C++ users have (void)var; to suppress unused variables warnings.
#Pang in the comments reports that the variable discards can be used for warnings suppression:
_ = variable;
This is probably available since C# 7.0, that introduce such use of underscore in the language syntax. In previous versions of the language once could suppress unused variables warnings in C# with bitwise operators, for types where such operators are defined:
uint test1 = 12345;
test1 |= 0; // test1 is still 12345
bool test2 = true;
test2 &= false; // test2 is now false
Using such strategy is certainly fishy and to use as last resort. Better to upgrade language support and use variable discard syntax.
I need to suppress a specfic compiler warning in C#. Now I can do it like this:
#pragma warning disable 0649
private string _field;
#pragma warning restore 0649
Is there a way to do it like the following?
[SuppressCompilerWarning("0649")]
private string _field;
Because I only need to suppress warnings for this field, not a code block.
Note: I want to suppress the compiler warning, not the Code-Analysis warning.
Thanks!
Doesn't:
private string _field = null;
remove the warning as well?
No. You can do it project wide via a build flag, but otherwise a field is just another (small) block.
Of course, you could assign it a value somewhere... that'll make it happy ;-p (I'm assuming it is actually assigned a value via reflection or something?)