How to deal with Code Contracts warning CC1036 when using string.IsNullOrWhiteSpace? - c#

I have the following code contract:
public void F(string x)
{
Contract.Requires(!string.IsNullOrWhiteSpace(x));
throw new NotImplementedException();
}
When compiling, I get the following warning:
warning CC1036: Detected call to method 'System.String.IsNullOrWhiteSpace(System.String)' without [Pure] in contracts of method [...]
How to deal with it?
What's odd, is that I'm also using string.IsNullOrEmpty, which isn't marked as [Pure] as well, in other contracts and the rewriter does not have a problem with that.
My Contract Rewriter's Version is 1.9.10714.2.
This is the relevant part from the implementation of String class I'm using (retrieved from metadata):
#region Assembly mscorlib.dll, v4.0.0.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll
#endregion
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace System
{
// Summary:
// Represents text as a series of Unicode characters.To browse the .NET Framework
// source code for this type, see the Reference Source.
[Serializable]
[ComVisible(true)]
public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable, IComparable<string>, IEnumerable<char>, IEquatable<string>
{
// [...]
//
// Summary:
// [...]
public static bool IsNullOrEmpty(string value);
//
// Summary:
// [...]
public static bool IsNullOrWhiteSpace(string value);
Why is the [Pure] attribute missing?

Here we have two points:
1. Why is the [Pure] attribute missing in string class for IsNullorWhiteSpace function?
2. How to resolve the CC1030 warning issue?
I will try to discuss both.
1. Why is the [Pure] attribute missing? It's not missing, metadata does not seem to be showing this.
This may not be marked as Pure in previous version of .NET FX as, they were saying:
Yes, we need to make our checker sensitive to the disable pragma...
Sigh.
We currently don't have that implemented, but I've added it to our
work list.
Refer to the 5 year old discussion here.
But this has been marked as Pure in latest FX (4.6.1), Refer to .NET Framework 4.6.1, the new string class code.
[Pure]
public static bool IsNullOrWhiteSpace(String value) {
if (value == null) return true;
for(int i = 0; i < value.Length; i++) {
if(!Char.IsWhiteSpace(value[i])) return false;
}
return true;
}
Then Why CC1036?
This warning "CC1036" is from CodeContracts, developers have open this issue yesterday only (refer here).
Now why metadata is not spitting up Pure attributes, this is a different question, like for Equals method, Pure is added but only SecuritySafeCritical is displayed in metadata code.
[SecuritySafeCritical]
public static bool Equals(String a, String b, StringComparison comparisonType);
The same problem applies to Invariant(). Given the following code, the
same warnings are displayed:
private string testString = "test";
[ContractInvariantMethod]
private void TestInvariant()
{
Contract.Invariant(!string.IsNullOrWhiteSpace(testString));
}
How to resolve?
As others are also suggesting, create another method, mark it as Pure and call this in your contract condition.

Going through a pure delegate will make the warning go away. Predicate<T> is already marked pure, so you can just use that to work around the bug:
// Workaround for https://github.com/Microsoft/CodeContracts/issues/339
public Predicate<string> IsNullOrWhiteSpace = string.IsNullOrWhiteSpace;
public void F(string x)
{
Contract.Requires(!IsNullOrWhiteSpace(x));
throw new NotImplementedException();
}

Although kind of ugly, you can wrap the function string.IsNullOrWhiteSpace with an extension method and mark this new function as Pure.

I just encountered the exact same problem. I'm using VS2015, so it does not seem to be related to VS version. I also tested the exact same code on .NET 4.0, 4.5.1 and 4.6, without getting the warning.
Like others have commented before me, the IsNullOrWhiteSpace is marked as [Pure] in .NET 4.6.1, and additionally should by default be considered pure by Code Contracts because it is in the System.String namespace. This makes it look like a bug, so I have submitted an issue to Code Contracts about this, so with some luck we will see an official answer soon.
While we wait for an answer, it is possible (like #Jaco suggests) to wrap it in an extension method and mark it as Pure yourself. Optionally, you can suppress the warning for that particular method like this:
[SuppressMessage("Microsoft.Contracts", "CC1036", Justification = "string.IsNullOrWhiteSpace is Pure")]
... but note that this will also suppress this warning from other Contract definitions in the same method.

Actually, this is a problem with the way .NET 4.6+ is compiled. See this GitHub pull request.
I was able to work around this by modifying the following file(s):
For Visual Studio 2013:
C:\Program Files (x86)\Microsoft\Contracts\MsBuild\v12.0\Microsoft.CodeContracts.Targets
For Visual Studio 2015:
C:\Progarm Files (x86)\Microsoft\Contracts\MsBuild\v14.0\Microsoft.CodeContracts.Targets
In both files, ensure the <Otherwise> child element of the first <Choose> element has the following content shown below:
...
<Choose>
<When Condition="'$(TargetFrameworkIdentifier)' == 'Silverlight'">
...
</When>
<Otherwise>
<Choose>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.0">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.0</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.5'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.5.1'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.5.2'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.6'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.6.1'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v3.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</Otherwise>
</Choose>
</Otherwise>
</Chose>
...
After making these changes to these files (per the GitHub pull request referenced above), I no longer received Code Contracts static analysis warnings for the use of String.IsNullOrWhiteSpace.
It should be noted that the referenced pull request has been merged into the main code for Code Contracts up on GitHub; they just haven't made a new release containing these changes yet.
Also, for those concerned about changing "system files", don't be. When the next version of Code Contracts is released, it will install updated versions of these files--and hopefully the changes will be included, and all will be right with the world. (Unless, of course, the changes aren't included--in which case, you'll be coming back here to reference this post to make those changes again ;) lol.)

Related

BenchmarkDotNet InProcessEmitToolchain Complete Sample

I'm looking at BenchmarkDotNet and benchmarking in general for the first time ever. I appear to be unable to run benchmarks using the normal BenchmarkRunner because of antivirus restrictions on our work laptops so I'm trying to use InProcessEmitToolchain, as documented here. However, in those samples and the ones listed here I see no entry point for the application that will actually trigger the benchmarks and I've gotten nowhere useful reading through the documentation.
Can anyone point me at a complete sample of how to use the InProcessEmitToolchain and/or jobs that explains how to use jobs in conjunction with an application entry point to run the tests?
I was facing the same problem with antivirus (Windows Defender) blocking BenchmarkDotNet. I was able to figure out how to change the toolchain setup, though I had to use InProcessNoEmitToolchain since InProcessEmitToolchain was also blocked.
The example below did not actually trigger the antivirus, but it shows how to define which toolchain to use:
[Program.cs]
using BenchmarkDotNet.Running;
using Benchmarks;
_ = BenchmarkRunner.Run<MaterializeTest>();
[MaterializeTest.cs]
using BenchmarkDotNet.Attributes;
namespace Benchmarks;
[Config(typeof(AntiVirusFriendlyConfig))]
[MemoryDiagnoser]
public class MaterializeTest
{
IEnumerable<int> _sequence;
[Params(10, 100, 1000, 10000)]
public int _size;
[GlobalSetup]
public void Setup()
{
_sequence = Enumerable.Range(0, _size).Select(i => Random.Shared.Next());
}
[Benchmark]
public IReadOnlyList<int> ToList() => _sequence.ToList();
[Benchmark]
public IReadOnlyList<int> ToArray() => _sequence.ToArray();
}
[AntiVirusFriendlyConfig.cs]
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Toolchains.InProcess.NoEmit;
namespace Benchmarks;
public class AntiVirusFriendlyConfig : ManualConfig
{
public AntiVirusFriendlyConfig()
{
AddJob(Job.MediumRun
.WithToolchain(InProcessNoEmitToolchain.Instance));
}
}
[Benchmarks.csproj]
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
</ItemGroup>
</Project>
I ended up being unable to solve this even using the InProcesNoEmitToolchain - our AV software was too persistent. I solved it by getting our IT folks to give us a folder whitelist entry in the AV software where we could run benchmarking.
You can tweak the configuration with the toolchains you like:
var config = DefaultConfig.Instance
.AddJob(Job
.MediumRun
.WithLaunchCount(1)
.WithToolchain(InProcessEmitToolchain.Instance));
Or alternatively
var config = DefaultConfig.Instance
.AddJob(Job
.MediumRun
.WithLaunchCount(1)
.WithToolchain(InProcessNoEmitToolchain.Instance));
And pass it to the Run method (building on the program from Andreas Warberg)
_ = BenchmarkRunner.Run<MaterializeTest>(config);

What is the difference in Marshaling between Windows and Linux for .NET Core?

I'm trying to migrate existing library to .NET Core to be able to run it under Linux.
When using the library in Linux, the runtime throws System.ArgumentException:
An unhandled exception of type 'System.ArgumentException' occurred in ConsoleApp6.dll: 'Type 'ConsoleApp6.MyStruct' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.'
Stack trace:
at System.Runtime.InteropServices.Marshal.OffsetOfHelper(IRuntimeFieldInfo f)
at ConsoleApp6.Program.Main(String[] args) in C:\Users\user\source\repos\ConsoleApp6\ConsoleApp6\Program.cs:line 10
In Windows, it works as expected.
Here a simple Console app that demonstrates the issue:
using System;
using System.Runtime.InteropServices;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine((Int32) Marshal.OffsetOf<MyStruct>("buffer"));
Console.ReadLine();
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct MyStruct
{
public Int16 number;
public byte[] buffer;
}
}
Here is the csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.7.12" />
</ItemGroup>
</Project>
I expect the output to be 4 in Windows and Linux, but in Linux it throws the above exception.
In .NET Core, you can't use OffsetOf<T>, per the Docs:
OffsetOf(Type, String)
Returns the field offset of the unmanaged form of the managed class.
OffsetOf<T>(String)
[Supported in the .NET Framework 4.5.1 and later versions]
Returns the field offset of the unmanaged form of a specified managed class.
In order for your code to work on Linux, you'll need to use the OffsetOf(Type, String) overload instead.
Console.WriteLine((Int32) Marshal.OffsetOf(typeof(MyStruct),"buffer"));
I've dug deeper into the CLR source code; and there's no apparent reason why your code shouldn't work on Linux. The defining characteristic of it being Marshalable, that I can see, is whether or not it's an Interface.
I'm going to dig deeper -- I see source code in the vm folder; but I'd also expect to see implmentation source code for each target environment, and I don't see that.

Auto-generate main method from referenced assembly

I am editing my question I think it is a little confusing and it does not explain what my intent is.
Edit:
My goal is that when my HelloWorld application references MyClassLibrary my code does not compile so that I ensure to initialize some code prior to running the main method. Kind of like a constructor of a class. When I reference MyClassLibrary I will like to run some code in there before running the main method of my HelloWorld application. NUnit has a similar functionality. When my HelloWorld application references NUnit I get the error: Error CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point. As #Alex pointed out that Main method that NUnit creates is auto-generated. I will like to auto-generate a main method with some custom code. How can I do that from MyClassLibrary without doing anything on my HelloWorld application just like NUnit does it?
OLD Question:
I want to perform the same behavior that NUnit tests perform that it prevents using a Main method. In this case the error that I need is a good thing. Let me explain what I mean.
I create a hello world application targeting the .net core
Project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
</Project>
Code file: (default hello world c# code)
If I then run that application it runs fine
Add a reference to NUnit and my project file now contains.
.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
</ItemGroup>
</Project>
When I try to compile the project I get the error:
Error CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point.
That means that there is another Main method. That method is probably located on the NUnit nuget package I am referencing. This is the error I am trying to replicate!.
Now this is how I try to replicate the same error:
I remove the NUnit nugget package having no references to NUnit on my hello world application.
Create a Project ClassLibrary1 with the following code:
.
public class MyLib
{
static void Main()
{
Console.WriteLine("fooooo");
// do something
}
}
Have my hello world application reference that project:
When I compile I get no errors even though there are 2 Main methods!
How does NUnit manages to prevent using a Main method? How can I replicate the same behavior? I want to create an assembly that when referenced it prevents executing the Main method.
It's just Microsoft.NET.Test.Sdk making build fail.
Adding <GenerateProgramFile>false</GenerateProgramFile> into <PropertyGroup> makes it compile and work anyway.
But adding another class with static void Main to the application makes build fail again regardless <GenerateProgramFile>.
In your example build fails because Microsoft.NET.Test.Sdk adds some auto-generated code to your application before compilation. That code is in ...\.nuget\packages\microsoft.net.test.sdk\16.2.0\build\netcoreapp1.0\Microsoft.NET.Test.Sdk.Program.cs. It's a class with another Main:
// <auto-generated> This file has been auto generated. </auto-generated>
using System;
[Microsoft.VisualStudio.TestPlatform.TestSDKAutoGeneratedCode]
class AutoGeneratedProgram {static void Main(string[] args){}}
BTW: it's absolutely legal to have Main method in another assembly. You just cannot have 2 Mains in one exe. But you can have any number of them in dll like this:
public class Class1
{
public static void Main() { }
public static void Main(string[] args) { }
}
public class Class2
{
public static void Main() { }
public static void Main(string[] args) { }
}
It compiles.
Update:
I found the solution. It's all about installing nuget, not just adding a reference.
Create a .NET Core Class Library and name it MyCoreLib.
Add MyCoreClass.
namespace MyCoreLib
{
public static class MyCoreClass
{
public static void Initialize()
{
System.Console.WriteLine("Initialized from 'MyCoreLib'");
}
}
}
Build the library.
Create the following file structure:
├───nuget
└───src
│ MyCoreLib.nuspec
│
├───build
│ └───netcoreapp2.1
│ ForcedEntryPoint.cs
│ MyCoreLib.targets
│
└───lib
└───netcoreapp2.1
MyCoreLib.dll
MyCoreLib.nuspec
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>MyCoreLib</id>
<version>1.0.0</version>
<authors>MyCoreLib</authors>
<owners>MyCoreLib</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Some description here</description>
<dependencies>
<group targetFramework=".NETCoreApp2.1" />
</dependencies>
</metadata>
</package>
ForcedEntryPoint.cs
//╔════════════════════════════════════╗
//║ This code was added automatically. ║
//║ Do not change or remove it. ║
//╚════════════════════════════════════╝
public static class ForcedEntryPoint
{
public static void Main(string[] args)
{
MyCoreLib.MyCoreClass.Initialize();
}
}
MyCoreLib.targets
<Project InitialTargets="ForceEntryPoint" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<ForcedEntryPoint Condition="'$(ForcedEntryPoint)' == ''">$(MSBuildThisFileDirectory)ForcedEntryPoint$(DefaultLanguageSourceExtension)</ForcedEntryPoint>
<ForceEntryPoint Condition="'$(ForceEntryPoint)' == ''">true</ForceEntryPoint>
</PropertyGroup>
<Target Name="ForceEntryPoint" Condition="'$(ForceEntryPoint)' == 'true'">
<ItemGroup>
<Compile Include="$(ForcedEntryPoint)"/>
</ItemGroup>
</Target>
</Project>
Use NuGet Commandline to build a package like this:
D:\nugetwalkthrough\nuget>D:\nugetwalkthrough\nuget.exe pack D:\nugetwalkthrough\src\MyCoreLib.nuspec
Create a .NET Core Console App and make sure it works.
Install the created package.
Try to run the application and get error:
CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point.
Remove the Main method from the application, run it and see it prints Initialized from 'MyCoreLib'.
Put the Main method back to the application and change the project file so that <PropertyGroup> contains <ForceEntryPoint>false</ForceEntryPoint>
Now it compiles and prints Hello World! from its own Main method.
Changing <ForceEntryPoint> to true makes it use another entry point (not that one of the application) again.
I think you should learn how to make multiple project under same solution.
So helloworld is main project.
Then create new test project helloworld.test as test project use Add a reference to NUnit there.
now all will work fine you can change your start up project to helloworld.test and debug or run it from visual studio or command line.
Anyway I never saw a test project inside main project in professional coding. May be for testing we comment main method and run test case.
Test project is also Executable.

Get Assembly From C# Project File

I am trying to make a simple WinForm tool to assist with code generation, and I was wondering if it was possible to get the Assembly of one project into a different one that presides in a different solution. I want the form to show all of the classes and then properties for each class, and the easiest/best way I can think of doing that is like:
private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
{
return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray();
}
If the user selects a .csproj file, is it possible to get the Assembly? Or is there a different way to get the classes/properties without recursively searching the project folder and parsing the files?
The csproj file will contain the assembly name and the output directory.
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AssemblyName>MyAppAssemblyNameOnly</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
</PropertyGroup>
</Project>
You'll have to add .dll suffix to it to get the actual file name.
The Output Path can be found in the different Configuration <PropertyGroup> nodes.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
There's a couple of problems I can think of right off the bat.
The DLL may not be built and so it won't exist.
There are many different configurations with there being Debug and Release by default. You'll have to decide which one to look for.
For ease, you may just want to make the user feed you a DLL if the project is not part of the solution and you don't actually need anything else.
You can also look into Roslyn and parse the files with Roslyn to get you all of the information you need too.
Here's an example straight from their page. Seems super simple and straightforward. Kind of larger than I want, but don't want to just give a single link-only suggestion.
class Program
{
static void Main(string[] args)
{
SyntaxTree tree = CSharpSyntaxTree.ParseText(
#"using System;
using System.Collections;
using System.Linq;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}");
var root = (CompilationUnitSyntax)tree.GetRoot();
var firstMember = root.Members[0];
var helloWorldDeclaration = (NamespaceDeclarationSyntax)firstMember;
var programDeclaration = (ClassDeclarationSyntax)helloWorldDeclaration.Members[0];
var mainDeclaration = (MethodDeclarationSyntax)programDeclaration.Members[0];
var argsParameter = mainDeclaration.ParameterList.Parameters[0];
}
}

Disabling OBSOLETE error in C#

I am using the Microsoft TFS API and one of the properties on one of the interfaces has been marked as Obsolete and it instructs me to use a different property. Unfortunately the property the API wants me to use is used by TFS2010 and not TFS2008.
I have tried doing this:
#pragma warning disable 0612, 0618
request.CommandLineArguments = arguments;
#pragma warning restore 0612, 0618
But I still get the error that CommandLineArguments is obsolete. Is there anyway to suppress this?
EDIT
Unfortunately this is not showing up as a 'Warning as Error', in fact Treat Warning's As Error's is turned off in my project. Here is a screen cap of the offending code as well as the error list
EDIT 2:
After using ILSpy the CommandLineArguments property looks like this in the TFS2010 API:
[Obsolete("This property has been deprecated. Please remove all references. To pass command line arguments to MSBuild.exe, set the ProcessParameters property.", true)]
string CommandLineArguments
{
get;
set;
}
Unfortunately I don't think there is a way to tell the compiler to ignore the error that the Obsolete attribute is causing.
EDIT 3
As #Peter Ritchie points out this value could be set via reflection. As I thought through this problem though my guess is that if Microsoft set the property to throw an exception even if you did set it via reflection I doubt that the value would be referenced anywhere.
Visual Studio 2015
Build failing due to [Obsolete]?
This would only occur if "Treat Warnings As Errors" is enabled, and there is a method with the [Obsolete] attribute.
Method 1: Downgrade error to warning
Add <WarningsNotAsErrors>612,618</WarningsNotAsErrors> in the .csproj file (repeat for all sections):
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<WarningsNotAsErrors>612,618</WarningsNotAsErrors>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
If dealing with many .csproj files, see Appendix A: Notepad++ for search and replace.
Method 2: Ignore error in file
Note: This method is not recommended, because it hides the warnings for methods marked [Obsolete]. We still want to see a list of
all calls to obsolete methods so we can upgrade them.
Use #pragma warning disable 612,618
Method 3: Ignore error in project
Note: This method is not recommended, because it hides the warnings for methods marked [Obsolete]. We still want to see a list of
all calls to obsolete methods so we can upgrade them.
Edit the project (repeat for all sections):
Method 4: Ignore error in project
Note: This method is not recommended, because it hides the warnings for methods marked [Obsolete]. We still want to see a list of
all calls to obsolete methods so we can upgrade them.
Manually edit your .csproj to disable warnings for specific errors. Add the tag <NoWarn>612,618</NoWarn> (repeat for all sections):
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<NoWarn>612,618</NoWarn>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
Appendix A: Notepad++ for search and replace
Have a lot of files? No problem!
Open all .csproj files in NotePad++, then:
Find: <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Replace: <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\n\t<WarningsNotAsErrors>612,618</WarningsNotAsErrors>
Following works for me:
#pragma warning disable 612,618
request.CommandLineArguments = arguments;
#pragma warning restore 612,618
notice no leading 0 in the numbers
EDIT:
Okay, your assembly has the "true" argument in the ObsoleteAttribute constructor. This means you can't use the property and not get an error.
If you can't re-write your code to avoid using this property, you'll have to invoke the property setter via reflection, for example:
request.GetType().GetProperty("Number").SetValue(request, arguments, null);
and getting is similar:
(string)request.GetType().GetProperty("CommandLineArguments").GetValue(request, null);
Just in case anyone else stumbles on this.
If you mark the method in which you set the property as Obsolete and DONT mark it as true the compiler will ignore the interior error throwing your higher level warning instead which you can ignore.
IE
[Obsolete("Cause it aint",false)]
public void Foo(object arguments)
{
request.CommandLineArguments = arguments;
}

Categories