16

In my test project, I've got private fields that are not assigned to in the code, but are assigned with reflection.

When compiling I get warnings like:

Warning CS0649 Field 'CLASSNAME.FIELDNAME' is never assigned to, and will always have its default value null

I've tried adding <NoWarn>649</NoWarn> to the first PropertyGroup in the xproj. But I still get the errors.

Does NoWarn not work in DNX? Or am I doing something wrong? Is there any other solution to the problem?

Allrameest
  • 4,364
  • 2
  • 34
  • 50
  • 1
    Well, the bigger problem isn't the warning - it's the implications of the warning. It's perfectly legal for a future compiler to drop the field altogether if it's never used and private. Is there no better way to write your code rather than just hiding the entirely reasonable warnings? – Luaan Jun 25 '15 at 08:16
  • The fields are used, they are just not assigned to. It would be crazy for the compiler to remove those. Also, the InitializeFixture in FakeItEasy depends on having unassigned fields. When asking if I'm doing something wrong I'm talking about how I try to disable the warning. Not how the code is written. – Allrameest Jun 25 '15 at 13:38
  • But as far as the compiler is concerned, they will always be `null`, thus all reads from the field can be replaced with just `null`. In any case, if you want to stick to that kind of usage, I've always used `#pragma` to disable warnings - you might want to try that. – Luaan Jun 25 '15 at 13:47
  • 1
    Yes, `#pragma warning disable 0649` works. But instead of having those in my test classes, I would like something that disables the warnings for the whole test project. – Allrameest Jun 25 '15 at 15:16

2 Answers2

8

Sample code:

class Example {
    private string warningHere;    // CS0649
    void UseField() {
        Console.WriteLine(warningHere);
    }
}

You have to convince the compiler that you know what you're doing, it refuses to consider the possibility that you use Reflection to poke a value into the field. That's pretty simple to do:

    private string warningHere = null;  // Fine

You might object "But that's completely pointless! The CLR already initializes the field to null!". Which is certainly true. No harm done however, eliminating superfluous code like this is the job of the jitter optimizer. It is particularly good at removing needless null assignments.


I could have <NoWarn>0649</NoWarn> in the csproj

Do keep in mind that this is equivalent to solving a local problem with a global sledgehammer. This warning is pretty important, you want to have it in effect for all the code you compile. Just to demonstrate, in the above snippet change class to struct, keep the reflection code the same. And note that you cannot get give that warningHere field a value. A side-effect of the struct getting boxed before it is passed to FieldInfo.SetValue(), only the boxed copy is updated. That's a nasty bug to diagnose if you don't have a warning to alert you.

Using #pragma warning in the source is okayish, but not superior, too easy to forget to restore it.

The project switched to building with MSBuild just two months ago, do make sure your pull isn't too old and that you switched as well. You can file a bug at github to remind them if the feature is still awol. And do consider scratching that itch if you can't wait, fix it yourself. The ultimate benefit of an open source project :)

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Setting the field to null works, but it's not what I'm looking for. For the old projects I could have `0649` in the csproj. I'm looking for something similar in the xproj. – Allrameest Jul 08 '15 at 07:53
  • I expanded the answer below the line, explaining why this is a bad idea. – Hans Passant Jul 08 '15 at 08:06
  • I know the downside to it. I'm not interested in a lecture about why it's a bad thing. I'm gonna run with scissors if I want to... :) – Allrameest Jul 08 '15 at 08:13
  • 1
    Hmya, that's where I tune out. If you don't want to fix it yourself then file a bug report with the project. – Hans Passant Jul 08 '15 at 08:21
  • "And note that you cannot get give that warningHere field a value, no matter what you try." Well as you said, the struct will be boxed - and then you can set the field on the boxed value, and unbox it later. It's perfectly doable. Not terribly useful, but doable. I do think "How do I ignore particular warnings" is a reasonable question. – Jon Skeet Jul 14 '15 at 06:01
0

Compiler options cannot be specified in the xproj file. Follow these steps to suppress a compiler warning:

  1. Open the project.json file of the project. All compiler options must be specified in this file.

  2. Add the compilationOptions section to the end of the file:

    "compilationOptions": { "noWarn": [649] }

  3. Save the file and wait for few seconds until you see the "Package Restore completed" message in the status bar of Visual Studio.

  4. Rebuild the project.

This should suppress the warning. However, sometimes (probably a bug), the changes you make to project.json do not take effect even after a clean build. In this case, by making additional dummy changes to the file and rebuilding usually solves the problem.

Hadi Brais
  • 22,259
  • 3
  • 54
  • 95
  • That would be nice, but I can't get it to work. And I can't find any trace of it in the [dnx code](https://github.com/aspnet/dnx/blob/dev/src/Microsoft.Framework.Runtime/CompilerOptions.cs). – Allrameest Jul 14 '15 at 13:05
  • @Allrameest Yes you will not find it there. However, I just tried it and it does work. Try to change `project.json` (suppress another warning) in any way and then follow the steps. – Hadi Brais Jul 14 '15 at 13:15
  • Tried it, doesn't work. And find it hard to see how it could work if there's nothing in the code base for it... – Allrameest Jul 14 '15 at 13:23
  • @Allrameest Note that `CompilerOptions` does not indicate which options are supported and which aren't. It is used to reference only those compiler options from parts of the code. Also as I said, the changes made to `project.json` may or may not take effect when you build. The best way to go around this is to perform a clean build and change the file a couple times. – Hadi Brais Jul 14 '15 at 13:49