Search code examples
c#code-contracts.net-4.6

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


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?


Solution

  • 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();
    }