isnot operator

Topics: C# Language Design
May 2 at 3:10 AM
VB is planned to be getting support for TypeOf IsNot in the next release but the C# column has an N/A. I don't think this is exactly true, as, in my opinion, C# would surely benefit from adding an isnot operator.

My eyes tear just a little bit each time I have to write this ugly code:
if(!(c is Foo)) { ... }
This would be so much nicer:
if(c isnot Foo) { ... }
An isnot operator would make this sort of code far easier to read and reason about at a glance.

I opened an issue on the tracker so people could vote on this, but I'd also like to see what other's thoughts are.
May 5 at 3:59 PM
I'd like to see this introduced as well.

Bearing in mind that they haven't introduced any 'full' keywords since version 1.0, I don't know whether it would be feasible for 'isnot' to be a 'contextual' keyword here but, if it were, it would be great to have it :)
May 5 at 5:52 PM
+1. I've also missed that operator on more than one occasion.
May 5 at 6:09 PM
yeah i also feel the need for something like this, but "isnot" feels not really C#'ish
May 5 at 6:54 PM
I suppose you could use 'isnt' or 'aint' instead but 'isnot' sounds best to me.
May 5 at 7:27 PM
Having a contraction be a language keyword would be pretty strange indeed.

@Suchiman I'm not sure why it doesn't feel C#ish to you. C# has many multi-word keywords already (typeof, namespace, readonly, sizeof, stackalloc) and it has negative keywords (unchecked, unsafe). The only other reasonable thing I can think of would be is!, but this would make it the only keyword to mix English and special characters, which seems weird. Also, isnot is also consistent with VB, which has always been important to the languages team.
May 5 at 7:39 PM
Edited May 5 at 7:41 PM
MgSam wrote:
Also, isnot is also consistent with VB, which has always been important to the languages team.
I think thats partly the reason, the little difference between C# and VB. While the Feature would be very nice, isnot as Syntax, maybe only because of "not", feels like VB. But you are also right about the keywords, mhhh. is! feels more like C#, though for consistency with other comparisons, it would have to be !is and again, you're right, that also looks a bit weird.

After all, i can't choose a preferred Syntax, but it would be still nice to have something like that
May 7 at 10:43 AM
The consistent C# would be !is

I think better syntax would be: (just support to add ! before condition)
if !(c is Foo){ ... }
or simple and uterly crazy :)
else(c is Foo){ ... }
May 7 at 4:50 PM
Edited May 7 at 4:51 PM
ttxman wrote:
I think better syntax would be: (just support to add ! before condition)
I would like C-like languages to allow if !(condition) as a syntax, so that positive and negative composite conditions would require the same depth of parentheses; that might be worth proposing as a separate idea. If is were ever extended to support VB's very useful meaning as a reference-equivalence operator, the "spelling" might have to be !is to avoid any possible ambiguity. Even if the present token only allows checking types, using "!is" would leave open the possibility of allowing the "is" operator to be used for testing references along with its mate "!is". Using a token like "isnot" would be more likely to preclude such usage.
May 7 at 5:12 PM
@MgSam: if I had to quote you from other threads, I should post these lines of yours ...
I'm very much supportive of syntax sugar features that I believe solve common problems by making code less verbose or more readable. I think what sets C# apart from many other languages is that a major tenant of its language design has been "solve real problems" rather than do things because they are interesting from a theory standpoint.
... since I don't see a real problem here.

Having said that, I do believe that your proposal will improve readability in a common situation (not problem), so I will give my +1 to "isnot" (or "!is").
May 7 at 5:33 PM
@Ultrahead I think that you should not take me disagreeing with your feature suggestion elsewhere so personally. In this case, I believe the syntactic change I proposed is a minor addition, adds symmetry to the language with is and with VB, and makes the code less verbose and more readable. It's not an entirely new construct with new semantics that fulfills only a narrow use case.

@supercat I like your suggestion, though I think more generally it points to the question: why are parenthesis required for if statements at all? if boolean { } seems just as clear to me. Though I'm undecided if I think it's a good idea, it's interesting to consider if they're really needed. After all, parenthesis for empty constructors with initializer lists are optional, parenthesis for lambdas with a single parameter are optional; it certainly is not unprecedented in C# to elide parenthesis.

Still, I'd like some form of isnot/is!/!is operator. Having just an is with no negative form is equivalent to there only being an == operator but no !=. You don't really need the != operator to write correct code, but it makes it a lot more readable.
May 7 at 5:50 PM
Edited May 7 at 5:59 PM
@MgSam: I don't take things personally (if I were, I wouldn't even post my plus 1 here). On the contrary, I'm using your exact rationale to demonstrate that, at least imho, it also applies here, since having !(c is Foo)` is not a problem, and thus your suggestion is not a fix but an improvement to readability. Whether it is a minor or major addition -or the amount of work to implement it, which I don't know ex ante- does not occlude that fact. Regarding how narrow a use case is, YMMV, since I don't use the "is" operator as much as I face situations where I need a repeat statement. In spite of the latter, I think this improvement should be introduced to the language.
May 7 at 6:41 PM
Ultrahead wrote:
I don't use the "is" operator as much as I face situations where I need a repeat statement...
What would you think expanding the use of is operator to reference comparisons? I suspect a lot of code uses == in places where reference comparison is desired and would continue be desired even if a future version of the object were to include an equality-check operator. At present, if code wishes to check whether x and y are the same reference, independent of any overloads that might exist, it is necessary to use the rather clunky Object.ReferenceEquals(x,y) or (Object)x == (Object)y [casting only one operand would not preclude the compiler from using an overload defined by the other type between itself and Object] Not only are those forms excessively verbose; they also compile (producing useless code) even in cases where a reference-equality test would make no sense.

Common practice from what I've seen is to use == for types which are not expected to overload the equality operator, but this may pose dangers. If a type Foo<T> uses == with T, then in the absence of generic constraints the operator will perform a reference comparison, but if T is later constrained to a type which overloads ==, any code which used == for reference comparison will fail and may only be corrected by identifying which uses of x==y are deliberately invoking the overloadable operator and which ones really mean Object.ReferenceEquals(x,y). Allowing code to use is for the latter case, and deprecating the use of == for that purpose would avoid such problems.
May 7 at 6:52 PM
Edited May 7 at 6:53 PM
MgSam wrote:
why are parenthesis required for if statements at all? if boolean { } seems just as clear to me.
They are required because the braces on the following block are optional. Given that expression are allowed to start with unary minus signs, and expressions--even those which start with unary minus signs--are a form of statement, the expression if x==a()-b()-c(); could mean either if (x==a()) -b()-c();" or if (x==a()-b()) -c();. The use of Then in Pascal and VB.NET eliminates the need for closing parentheses, and the use of a line break following Then in VB.NET means that an if/elseif/elseif/else/endif will only require one block marker at the end, rather than a "begin/end" pair for each controlled statement group.
May 7 at 6:56 PM
I should have been clearer, but I meant for a block denoted with curly braces. Obviously without curly braces you'd have no way of knowing where the body of the if statement starts.
May 7 at 7:02 PM
Edited May 7 at 7:04 PM
@supercat: That is an interesting proposal.

If I understand you correctly, both is and the proposed !is will compare identities (that is, Object.ReferenceEquals(x,y)) and == will compare states (that is to say, x.Equals(y)), right?

If implemented, the example case were many write if(mystringref == otherstringref) (instead of, if(mystringref.Equals(otherstringref)) for default culture and case checking) would be over since it would mean something similar to if(mystringref == "This global string stored in a constant table") instead of identity comparison.

I don't know how accepted your proposal would be from the viewpoint of other devs (and MSFT), but imho, you should open a new thread to find out since it sounds reasonable.
Jun 16 at 6:46 PM
ttxman wrote:
The consistent C# would be !is
+1 for !is, no new keywork, only syntactic sugar to write more readable code !(instance is SomeType) is at least ugly.
Jun 16 at 9:42 PM
Indeed, ! and is appear relatively often together but in my opinion not often enough to warrant yet another keyword (which wouldn't even add any new functionality to the language).
Jul 7 at 1:16 PM
isnt
feels more "C#-ish".
if(a isnt Foo)
{
  ...
}
Jul 30 at 10:21 PM
!is ++
Aug 5 at 11:28 PM
Disclaimer: I don't actually like perl very much, and I promise never to use it as an example ever again.

But I have to admit, the "unless" keyword has some appeal:
unless (a is Foo)
{
    ...
}
And I also have to admit that 50% of the appeal stems from the fact that I laugh every time I see it. Not sure why. Maybe it's just me?