tags:

views:

2029

answers:

8

This is a silly question, but you can use this code to check if something is a particular type...

if (child is IContainer) { //....

Is there a more elegant way to check for the "NOT" instance?

if (!(child is IContainer)) { //A little ugly... silly, yes I know...

//these don't work :)
if (child !is IContainer) {
if (child isnt IContainer) { 
if (child aint IContainer) { 
if (child isnotafreaking IContainer) {

Yes, yes... silly question....

Because there is some question on what the code looks like, it's just a simple return at the start of a method.

public void Update(DocumentPart part) {
    part.Update();
    if (!(DocumentPart is IContainer)) { return; }
    foreach(DocumentPart child in ((IContainer)part).Children) {
       //...etc...
+47  A: 
if(!(child is IContainer))

is the only operator to go (there's no IsNot operator).

You can build an extension method that does it:

public static bool IsA<T>(this object obj) {
    return obj is T;
}

and then use it to:

if (!child.IsA<IContainer>())

And you could follow on your theme:

public static bool IsNotAFreaking<T>(this object obj) {
    return !(obj is T);
}

if (child.IsNotAFreaking<IContainer>()) { // ...


Update (considering the OP's code snippet):

Since you're actually casting the value afterward, you could just use as instead:

public void Update(DocumentPart part) {
    part.Update();
    IContainer containerPart = part as IContainer;
    if(containerPart == null) return;
    foreach(DocumentPart child in containerPart.Children) { // omit the cast.
       //...etc...
Mehrdad Afshari
Very nice extension method (IsNotAFreaking
Hugoware
Not the only way, see mine below...
ck
ck: I meant in the sense of operators, there's no `IsNot` thing.
Mehrdad Afshari
+1 for IsNotAFreaking
Joseph
nice answer!....
Vimvq1987
+7  A: 

Why not just use the else ?

if (child is IContainer)
{
  //
}
else
{
  // Do what you want here
}

Its neat it familiar and simple ?

Saint Gerbil
Nothing wrong with it - this is just a nitpick question. I wanted to immediately exit a function if something was not a particular type. I've done it (!(child is Something)) forever now, but I thought I'd make sure there wasn't a better way.
Hugoware
+3  A: 

Ugly? I disagree. The only other way (I personally think this is "uglier"):

var obj = child as IContainer;
if(obj == null)
{
   //child "aint" IContainer
}
BFree
This won't work if the target type is a value type.
Mehrdad Afshari
Hmm.. Good point, I didn't think of that.
BFree
@Mehrdad - Nullable ? would enable it to work, not that this should be used. It's just an example of an uglier way.
Stevo3000
@Steveo3000: Yes, but you should explicitly mention ? is the `as` clause. `obj as int` is a always a compile time error.
Mehrdad Afshari
@Mehrdad - Agreed, BFree could edit his post to reflect this. Giving us 'obj as int?'.
Stevo3000
@Stevo3000: I don't think anything is wrong with it, however. IContainer feels like an interface rather than value type. Just wanted to point out it requires care on value type and is not always a direct translation of `is` form.
Mehrdad Afshari
you could optionally do if (obj == default(IContainer)), which would take care of value types and reference types
Joseph
@Joseph: No. The problem is not with the `if` line. The problem is that `as` operator expects either a value-type or a `Nullable<T>` as the target type. Otherwise, it's a compile time error.
Mehrdad Afshari
+2  A: 

While the IS operator is normally the best way, there is an alternative that you can use in some cirumstances. You can use the as operator and test for null.

MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}
Muad'Dib
+3  A: 

The is operator evaluates to a boolean result, so you can do anything you would otherwise be able to do on a bool. To negate it use the ! operator. Why would you want to have a different operator just for this?

Brian Rasmussen
It's not a different operator. I was wondering if there was a keyword that would let me drop the extra set of parens. It's a major nit-pick, but I was curious.
Hugoware
Okay I understand. From your examples I got the impression that you were looking for a new, dedicated operator.
Brian Rasmussen
+2  A: 

The way you have it is fine but you could create a set of extension methods to make "a more elegant way to check for the 'NOT' instance."

public static bool Is<T>(this object myObject)
{
    return (myObject is T);
}

public static bool IsNot<T>(this object myObject)
{
    return !(myObject is T);
}

Then you could write:

if (child.IsNot<IContainer>())
{
    // child is not an IContainer
}

Enjoy, Robert C. Cartaino

Robert Cartaino
Missing a ! operator
sixlettervariables
+17  A: 

You can do it this way:

object a = new StreamWriter("c:\\temp\\test.txt");

if (a is TextReader == false)
{
   Console.WriteLine("failed");
}
ck
I like it. Simple and readable.
Dominic
This really works?
Frank V
@Frank - yep, the is keyword gives a boolean, which you can compare to false
ck
@Frank it works because `is` has higher precedence relative to `==`. The only reason you can't use `!x is f` is that it has less precedence than `!`.
Mehrdad Afshari
@Mehrdad - nice explanation
ck
+2  A: 

The extension method IsNot<T> is a nice way to extend the syntax. Keep in mind

var container = child as IContainer;
if(container != null)
{
  // do something w/ contianer
}

performs better than doing something like

if(child is IContainer)
{
  var container = child as IContainer;
  // do something w/ container
}

In your case, it doesn't matter as you are returning from the method. In other words, be careful to not do both the check for type and then the type conversion immediately after.

Jeff