C# : 'is' keyword and checking for Not

落爺英雄遲暮 提交于 2019-11-28 02:55:54
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...

You can do it this way:

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

if (a is TextReader == false)
{
   Console.WriteLine("failed");
}

Why not just use the else ?

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

Its neat it familiar and simple ?

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
}

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

var obj = child as IContainer;
if(obj == null)
{
   //child "aint" IContainer
}

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?

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.

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 {}

This hasn't been mentioned yet. It works and I think it looks better than using !(child is IContainer)

if (part is IContainer is false)
{
    return;
}

While this doesn't avoid the problem of parentheses, for the sake of people getting here via Google, it should be mentioned that newer syntax exists (as of C# 7) to make the rest of your code a little cleaner:

if (!(DocumentPart is IContainer container)) { return; }
foreach(DocumentPart child in container.Children) {
    ...

This avoids the double-cast, the null-check, and having a variable available in scopes where it could be null.

if (child is IContainer ? false : true)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!