Resharper and Code Contracts not playing well together - c#

I'm using Resharper 5.x to do compile-time analysis and it's usually pretty good about it, but it doesn't seem to be applying code contracts to its logic. I have something like the following, but I'm getting an issue on the marked line.
public void Method(int arg)
{
Contract.Requires(this.NullableValueType != null);
this.Method2(
arg,
this.NullableValueType.Value, // [1]
this.ReferenceType);
}
[1] ends up getting highlighted with "Possible 'System.InvalidOperationException'". Is there a way to get rid of this error without turning off the check?

While admittedly Resharper could be more intelligent and take contracts into account, unfortunately currently it doesn’t.
I would recommend to make the line more explicit. Instead of
this.NullableValueType.Value
you could write
this.NullableValueType ?? <something>
where the “something” is, of course, something that doesn’t matter because it never happens (for example, new ThatValueType()).

Related

NUnit - Equal(this, that), True(this == that) or That (this, Is.EqualTo(that))?

Our house framework uses a generic class, DBField<T>, to emulate entity fields with databases that aren't compatible with Entity Framework (like, Oracle 11 or Sybase).
We're trying to make it as transparent as possible (again, like entity fields) so that the following code works:
DBField<int?> z_intLength = 2;
while (z_intLength <= 5)
{
z_intLength++;
}
//[...]
DBField<int?> z_intMaxLength = 10;
if (z_intLength > z_intMaxLength)
{
}
The above works nicely. We've used public static implicit operator DBField<T>(T value) and public static implicit operator T(DBField<T> value), along with overriding == and the other comparison operators, as well as implementing IEquatable<DBField<T>>, IComparable, and IComparable<DBField<T>>.
Now we're trying to put DBField<T> through NUnit tests, in which we're rather new.
Notably, we're trying our hand with various equivalents:
string z_strComment = "Comment";
_objOrder2.OrderComment = z_strComment;
//[...]
Assert.True("Comment" == _objOrder2.OrderComment);
Assert.That("Comment", Is.EqualTo(_objOrder2.OrderComment));
Assert.That(_objOrder2.OrderComment, Is.EqualTo("Comment"));
Assert.Equals("Comment", _objOrder2.OrderComment);
The first two assertions pass and the next two fail.
There seems to be a difference in the inner workings of each assertion. Can someone explain what it is?
More precisely, debugging with breakpoints seems to indicate that Assert.That("Comment", Is.EqualTo(_objOrder2.OrderComment)) tests _objOrder2.OrderComment.Equals("Comment"); I'd expect it the other way around. Am I missing something?
I understand that True() and Equals() are older than That(). Which ones are preferable in which situations?
There are 2 things at play here:
How useful the error message from NUnit is if the test fails
What style of NUnit API you're using
Assert.True("Comment" == _objOrder2.OrderComment)
If this test fails, you get a message like "Expected true, was false". Unhelpful, as it doesn't tell you what the value of _objOrder2.OrderComment actually was.
Assert.Equals("Comment", _objOrder2.OrderComment);
Assert.That(_objOrder2.OrderComment, Is.EqualTo("Comment"));
These two are equivalent, the first one uses a slightly shorter syntax, the second one uses a more extensible constraint model (you can write your own assertions, e.g. Assert.That(x, new MyConstraint(y))).
If the test fails, you'll get something like Expected "Comment", was "Actual Value". That's a bit more helpful.
Assert.That("Comment", Is.EqualTo(_objOrder2.OrderComment));
This one's backwards. If it fails, you'll get something like Expected "Actual Value", was "Comment", which is just wrong.
Regarding the older-style Assert.Equals vs the constraint model Assert.That, it's (annoyingly) up to personal preference. Personally I use Assert.Equals because I find it easier to read, but I'll use Assert.That over CollectionAssert when doing assertions on collections, and I'll also use it when writing my own assertions.
Read the comment from one of the NUnit developers below, about how they found that users found the Assert.That style more easily understood.

How to set Properties by Interface and not get compilerwarnings

I have a lot of classes that share a lot of properites and have a lot of common interfaces.
It happens very regularly that i want to construct an object with data from another object and they share an interface. To make that more easy i have this neat little method:
public static List<PropertyInfo> InterfaceProperties(Type type)
{
return new[] {type}
.Concat(type.GetInterfaces())
.SelectMany(i => i.GetProperties(BindingFlags.Instance | BindingFlags.Public)).ToList();
}
public static void SetFromSimilar<TInterface>(TInterface destination,TInterface source)
{
var properties = InterfaceProperties(typeof(TInterface));
foreach (var property in properties)
{
var val = property.GetValue(source, null);
property.SetValue(destination, val, null);
}
}
It works fantastic because now i can do this:
public class MyClass: IMyInterface
{
public MyClass(IMyInterface otherClass)
{
SetFromSimilar(this,otherClass)
}
....MyProperties.....
}
Now rider complains about non-nullable properties being uninitialized which makes sense. I know they are initialized but for the IDE thats hard to see and i get compilerwarnings. This throws me off because i see it marked as a potentialy error and i have to think everytime if there is something wrong.
Is there a substitute for my method where this will not happen?
Ok i got no answers so far. Is it not possible? Is this not a normal usecase? Is it somehow possible with net5?
The compiler warning:
C:\My\File\Path\MyClass.cs(10,16): warning CS8618: Non-Nullable-Eigenschaft "MyProperty" muss beim Beenden des Konstruktors einen Wert ungleich NULL enthalten.
Erwägen Sie eine Deklaration von "Eigenschaft" als Nullable. [C:\My\File\Path\MyProject.csproj]
It tells me to maybe make the property nullable which i absolutely don`t want.
The compiler and analyzers cannot usually (or easily) interpret reflection code, so it is quite reasonably unconvinced as to their assignment and nullability. If you know something is correct that the compiler can't verify: just add a suppression for the warning over that particular code block, via #pragma, a [SuppressMessage(...)] on the affected code, or a suppression file (which is just [assembly:SuppressMessage(...)] in a different file, with a Target to tell the compiler what it applies to). Rider may have some other ways of suppressing messages, via the context menu.
Note: if you go this route, you may also want to add assertions - especially in a DEBUG build - that what you belive to be true: is actually true.
If you're using C# 9, you could add a smattering of dammit (!) markers, or turn off nullability checking for that code.
Well yea, this does not look like a perfectly elegant solution to your problem, in my opinion. Here's some solutions I can think of, in order of elegance:
1. Quick & Brute force
Just tell rider to not complain about it with a #pragma statement, I believe in your case it should be this:
#pragma warning disable CS8618
[code that throws the warning]
#pragma warning restore CS8618
2. Write code to generate code
Write yourself a small application that extracts those common interfaces to autogenerate set-value code for each
3. Don't mix data with control code
If you need to set data on classes with different controllers, i.e. classes, put it into its own data class. Tadaaa, you just gained the ability of class inheritance for setting common values.

C# possible null pointer exception [duplicate]

Here is a piece of code:
IUser user = managerUser.GetUserById(UserId);
if ( user==null )
throw new Exception(...);
Quote quote = new Quote(user.FullName, user.Email);
Everything is fine here. But if I replace "if" line with the following one:
ComponentException<MyUserManagerException>.FailIfTrue(user == null, "Can't find user with Id=" + UserId);
where function implementation is following:
public abstract class ComponentException<T> : ComponentException
where T : ComponentException, new()
{
public static void FailIfTrue(bool expression, string message)
{
if (expression)
{
T t = new T();
t.SetErrorMessage(message);
throw t;
}
}
//...
}
Then ReSharper generates me a warning: Possible 'System.NullReferenceException' pointing on 1st usage of 'user' object.
Q1. Why it generates such exception? As far as I see if user==null then exception will be generated and execution will never reach the usage point.
Q2. How to remove that warning? Please note:
1. I don't want to suppress this warning with comments (I will have a lot of similar pieces and don't want to transform my source code in 'commented garbage);
2. I don't want to changes ReSharper settings to change this problem from warning to 'suggestion' of 'hint'.
Thanks.
Any thoughts are welcome!
P.S. I am using resharper 5.1, MVSV 2008, C#
Resharper only looks at the current method for its analysis, and does not recursively analyse other methods you call.
You can however direct Resharper a bit and give it meta-information about certain methods. It knows for example about "Assert.IsNotNull(a)", and will take that information into account for the analysis. It is possible to make an external annotations file for Resharper and give it extra information about a certain library to make its analysis better. Maybe this might offer a way to solve your problem.
More information can be found here.
An example showing how it's used for the library Microsoft.Contracts can be found here.
A new answer in old post...
Here a little sample of my code regarding how to use CodeContract via ContractAnnotation with Resharper:
[ContractAnnotation("value:null=>true")]
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
It is very simple...if u find the breadcrumb in the wood. You can check other cases too.
Have a nice day
Q1: Because Resharper doesn't do path analysing. It just sees a possible null reference and flags that.
Q2: You can't without doing either of what you provided already.
You do know (or expect) that this code will throw an exception if there is a null reference:
ComponentException<MyUserManagerException>.FailIfTrue([...]);
However, since there is no contract specifying this, ReSharper has to assume that this is just a normal method call which may return without throwing any exception in any case.
Make this method implement the ReSharper contract, or as a simple workaround (which only affects debug mode, therefore no performance penalty for release mode), just after the FailIfTrue call:
Debug.Assert(user != null);
That will get rid of the warning, and as an added bonus do a runtime check in debug mode to ensure that the condition assumed by you after calling FailIfTrue is indeed met.
This is caused by the Resharper engine. These "possible NullReferenceException" happen because someone (probably at Resharper) has declared/configured somewhere an annotation on the method.
Here is how it works: ReSharper NullReferenceException Analysis and Its Contracts
Unfortunately, sometimes, these useful annotation are just wrong.
When you detect an error, you should report it to JetBrains and they will update the annotations on the next release. They're used to this.
Meanwhile, you can try to fix it by yourself. Read the article for more :)
Please check if you have any user==null if check above the given code. If there is, then ReSharper thinks that the variable "can be null" so recommends you to use a check/assert before referencing it. In some cases, that's the only way ReSharper can guess whether a variable can or cannot be null.

"Does not contain whitespace" in Code Contracts?

I'm new to Code Contracts - just starting to try to figure it out. I just ran into something that I am not sure how to accomplish:
I have a certain private readonly field which can be publicly "got" via a property:
private readonly string name;
public string Name
{
get
{
return this.name;
}
}
This field should never be null, should never be empty, and should never contain any white space. So I put various "Requires" into the constructor to try to ensure those things:
public Thing(string name)
{
Contract.Requires<ArgumentNullException>(
name != null,
"Name must not be null");
Contract.Requires<ArgumentException>(
name.Length > 0,
"Name must have positive length");
Contract.Requires<ArgumentException>(
!name.Any(x => char.IsWhiteSpace(x)),
"Name must not include whitespace");
this.name = name;
}
Putting in a little code to try to violate these contracts shows that the static checker successfully catches violations of "not null" and "not empty", but it does not catch violations of "contains no whitespace". I guess this is unsurprising? I guess it does certain simple checks at compile time (like "!= null") but other more complicated ones (like the linq check for whitespace) aren't done except perhaps at runtime?
Anyway, I then added some invariants to the class to try to describe these same things:
[ContractInvariantMethod]
private void ContractInvariants()
{
Contract.Invariant(this.name != null);
Contract.Invariant(this.name.Length > 0);
Contract.Invariant(!this.name.Any(x => char.IsWhiteSpace(x)));
}
This resulted in the following warning (at least, with warning level set to high), on my constructor (quoted above):
CodeContracts: invariant unproven: !this.name.Any(x => char.IsWhiteSpace(x))
But the constructor is setting this.name to the value of a local variable that requires that same contract!
Are my Requires and/or my Invariant not doing what I intend them to do? Is there a way to make them do what I intend them to do? Should I even be trying to make them do what I intend them to do in the first place? Am I just fundamentally misunderstanding things here? Like I said, I'm totally new to this. Thanks for any guidance.
Code contracts aim to prove assumptions by reasoning about requires and ensures at compile time. But that problem is undecidable, so it is impossible to validate everything (not even with technology that will be invented within thousands of years, it is fundamentally - proven - impossible). Conservative algorithms can however prove a part of the statements and warn the programmer it is unable to prove other or prove that a contract will be harmed.
Your invariant has some problems that you call a Linq method within it, and that probably the Linq methods do not provide the (necessary) code contracts themselves to do the reasoning properly. You don't have to provide contracts for all methods. The system is sometimes able to reason about the code and reason about it oneself. But not always. For instance the code of an array list does not necessary provides an indication that the Count is always greater than or equal to zero...
Code contracts however have some builtin functions to work with collections like the Contract.ForAll functions:
Contract.Invariant(
Contract.ForAll(this.name, x => !char.IsWhiteSpace(x))
);
This has more chance to get validated, but again, there is no guarantee this will change much. Neither that the code contract will get proven, nor proven false.
You should use Contract.Invariant(!string.IsNullOrWhitespace(value))instead. It will cover all three cases at once and the CodeContract engine might be able to support it at compile time too.

Resharper warns about a null string (System.NullReferenceException)

Just want to be sure that I haven't been coding for too long ... But, this seems highly unlikely :
http://i.imgur.com/TBjpNTX.png
I create the var, check for null, return if it is, so there's no way I can see it as being null at that point :)
Resharper bug ?
Edit:
As per Igal Tabachnik answer, he's right, I'm using the following method extension:
public static bool IsNullOrEmpty(this string target)
{
return String.IsNullOrEmpty(target);
}
I find it much easier to read
if (some_string.IsNullOrEmpty())
// do something here
rather than the:
if (string.IsNullOrEmpty(some_string))
// do something here
Solution:
Igal Tabachnik was right. The only 2 missing pieces were:
Resharper -> Options -> Code Annotations (under Code inspection group) -> turn on for solution.
Give VS a couple of minutes to get refresh everything.
Your code suggests that IsNullOrEmpty() method you're using is your own custom Extension method. The "real" IsNullOrEmpty is a static method of string.
Short answer: if you change it to
if (string.IsNullOrEmpty(input_string))
return "...";
ReSharper will stop complaining.
Long answer: Since this is your own extension method, ReSharper has no way of knowing how the result of this method applies to your code. For this, ReSharper uses code annotations to figure out additional information about the code. One such annotation is called a Contract Annotation, and it is what ReSharper uses to figure out the result of the original string.IsNullOrEmpty() method. You can read more about it in the blog post.
Bottom line, if you want to use your own extension method, but have ReSharper understand it correctly, you have to apply the following Contract Annotation on it:
[ContractAnnotation("null=>true")]
public static bool IsNullOrEmpty(this string input)
{
...
}
Your IsNullOrEmpty()-method seems to be an own invention since the original one is a static method of System.String and not an extension method. ReSharper isn't able to figure that one out though if you use the original one it will see that no null-values can make it past.
var str = value as string;
if (string.IsNullOrEmpty(str))
return;
var unicorn = str.Contains("unicorn");

Categories