I have the following piece of code with warning Expression is always true
:
public class MyClass
{
private readonly IHubContext<NotificationHub> _hubContext;
public MyClass(
IHubContext<NotificationHub> hubContext)
{
_logHandler = logHandler;
_hubContext = hubContext;
}
foreach (string group in groups)
{
IClientProxy connection = _hubContext.Clients.User(group);
if (connection != null) // Expression is always true
{
}
}
}
I know that Resharper is very smart, however I cannot understand why it says Expression is always true
as IClientProxy
is reference type.
IClientProxy
resides in Microsoft.AspNetCore.SignalR
namespace.
Do you know why Resharper says Expression is always true
?
This is how User
is declared in public interface IHubClients<T>
:
public interface IHubClients<T>
{
/// <summary>
/// Gets a <typeparamref name="T" /> that can be used to invoke
/// methods on all connections associated with the specified user.
/// </summary>
/// <param name="userId">The user ID.</param>
/// <returns>A client caller.</returns>
T User(string userId);
}
UPDATE:
If I add ?
sign:
IClientProxy? connection = _hubContext.Clients.User(group);
Then I will get the following warning:
The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
UPDATE 1
Even if I use var
:
var IClientProxy? connection = _hubContext.Clients.User(group);
if (connection != null)
then warning is arised Expression is always true
:
CodePudding user response:
Firstly, we should note that the warning is from Resharper, and not the actual compiler. If you disable Resharper, that particular warning will go away.
That said, it is a valid warning. To understand why, consider the following interface definition:
public interface IDemo<T>
{
public T Func();
}
That definition states that Func()
will not return null. If it could return null, it would be defined using T?
thus: public T? Func();
A simple implementation of that interface could look like this:
public sealed class Demo<T>: IDemo<T> where T: new()
{
public T Func()
{
return new T();
}
}
This compiles OK. However, if you change the implementation of Func()
to:
public T Func()
{
return null;
}
you will get a real (not Resharper) compile error:
error CS0403: Cannot convert null to type parameter 'T' because it could be a non-nullable value type. Consider using 'default(T)' instead.
warning CS8603: Possible null reference return.
Now consider this code (where I chose an arbitrary type with a default constructor for illustration, in this case Random
):
IDemo<Random> test = new Demo<Random>();
if (test.Func() != null)
{
Console.WriteLine("Not null");
}
This provokes the Resharper warning that you're seeing, the reason being that IDemo<Random>.Func()
has been specified to return non-null, as explained above.
The method you are using is declared as public T IHubClients<T>.Client(String)
- i.e. it returns T
and not T?
- which means it can never (or should never) be null.
Thus when you check it for null, Resharper is warning you because you should not need to do that.