Avoid the == and! = Operators for generic type parameters, but can it compare to null?

According to the Directive Constraints on type parameters (C # Programming Guide) ), and I quote:

When applying class T restrictions: Avoid == and! = Operators in the type parameter, because these operators will be for reference identity only, not for equality of values. This is true even if these statements are overloaded in the type that is used as the argument. The following code illustrates this point; the output is false, even if the String class overloads the == operator.

In the following example:

public static void OpTest<T>(T s, T t) where T : class { System.Console.WriteLine(s == t); } static void Main() { string s1 = "target"; System.Text.StringBuilder sb = new System.Text.StringBuilder("target"); string s2 = sb.ToString(); OpTest<string>(s1, s2); } 

However, ReSharper (I just started using the demo / trial version to find out if I should do this) gives a hint / hint for checking parameters like this:

 public Node(T type, Index2D index2D, int f, Node<T> parent) { if (type == null) throw new ArgumentNullException("type"); if (index2D == null) throw new ArgumentNullException("index2D"); if (parent == null) throw new ArgumentNullException("parent"); } 

(T is limited where T : class, new() )

Can I safely follow ReSharper without encountering problems that the C # documentation is trying to explain to me?

+6
source share
5 answers

Yes, it is normal. The documentation says do not compare two parameters because you are doing a comparative comparison. The ReSharper code only offers that the link you submitted is not null, so it is safe.

In my opinion, the main reason C # docs recommends you not to do this, because if you, for example, execute == with two lines that were passed as T1 and T2 , it will do a comparative comparison. At any other time, when you execute stringA == stringB , it will compare the values ​​with the overload in the string class. This really just warns against doing these types of comparisons, because the operator overload that was commonly used (if you used this operator for two types declared in the local scope) is not.

+7
source

Yes.

Only a very strange implementation of the == operator will make x == null mean something other than ReferenceEquals(x, null) . If you use classes with such a strange implementation of equality, you have more problems than inconsistencies when checking for zero using the generic type argument.

+7
source

The documentation states that == will use reference comparison no matter what the actual type of T , even if it overloaded the == operator. In many cases, this is not what users expected.

In the case of resharper code, it compares the variable with the null number you want to be a reference comparison, not a comparison of values, so the information about you warns of the correct behavior here.

However, you could make it more explicit by writing something like this, just to be clearer:

 if(object.ReferenceEquals(type, null))//... 
+4
source

Yes, it’s generally normal to assume that null is a special case, and that it’s normal to do == or != On it. This is at least because the recommendation for overriding Equals says x.Equals(null) should be false .

If you did not have a T : class restriction, this will be a different story, since you will see some unexpected behavior for struct and nullable struct (you might want to make default(T) instead of null there).

And if you want to clearly indicate that yes, you know that you are comparing a reference to null , you can always use object.ReferenceEquals(x, null) (I would just go with == / != , Though).

+2
source

I would say that everything is in order.

null is special, so you are not doing the actual comparison between two reference variables, you just confirm that the reference variable is not a null reference.

Compare this, for example, with SQL. There you have a completely different syntax for comparison ( a = b ) and for null checking ( a is null ). The guiding principle is that you should avoid the former, but the latter is normal.

+1
source

Source: https://habr.com/ru/post/954637/


All Articles