web-dev-qa-db-fra.com

C #: mot-clé 'is' et vérification de Non

C'est une question idiote, mais vous pouvez utiliser ce code pour vérifier si quelque chose est d'un type particulier ...

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

Existe-t-il un moyen plus élégant de vérifier l’instance "NOT"?

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

Oui, oui ... question idiote ....

Parce qu'il y a une question sur ce à quoi le code ressemble, il ne s'agit que d'un simple retour au début d'une méthode.

public void Update(DocumentPart part) {
    part.Update();
    if (!(DocumentPart is IContainer)) { return; }
    foreach(DocumentPart child in ((IContainer)part).Children) {
       //...etc...
256
Hugoware
if(!(child is IContainer))

est le seul opérateur à y aller (il n'y a pas d'opérateur IsNot).

Vous pouvez construire une méthode d'extension qui le fait:

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

et ensuite l'utiliser pour:

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

Et vous pouvez suivre votre thème:

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

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

Mise à jour (en tenant compte de l'extrait de code de l'OP):

Puisque vous définissez la valeur par la suite, vous pouvez simplement utiliser as:

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...
278
Mehrdad Afshari

Vous pouvez le faire de cette façon:

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

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

Pourquoi ne pas simplement utiliser le reste?

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

C'est soigné, c'est familier et simple?

12
Mark Broadhurst

La façon dont vous l’utilisez est correcte mais vous pouvez créez un ensemble de méthodes d’extension pour créer "un moyen plus élégant de vérifier l’instance 'NOT'".

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

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

Ensuite, vous pourriez écrire:

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

Laid? Je ne suis pas d'accord. La seule autre façon (je pense personnellement que c'est "plus laid"):

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

La méthode d'extension IsNot<T> est un bon moyen d’étendre la syntaxe. Garder en tete

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

effectue mieux que de faire quelque chose comme

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

Dans votre cas, peu importe puisque vous revenez de la méthode. En d'autres termes, veillez à ne pas effectuer à la fois la vérification du type, puis la conversion du type immédiatement après.

3
Jeff

L'opérateur is évalue un résultat booléen afin que vous puissiez faire tout ce que vous seriez capable de faire autrement. Pour le nier, utilisez le ! _ opérateur. Pourquoi voudriez-vous avoir un opérateur différent juste pour cela?

3
Brian Rasmussen

Cela n'a pas encore été mentionné. Cela fonctionne et je pense que ça a l'air mieux que d'utiliser !(child is IContainer)

if (part is IContainer is false)
{
    return;
}
2
Todd Skelton

Bien que l'opérateur IS soit normalement la meilleure solution, il existe une alternative que vous pouvez utiliser dans certaines circonstances. Vous pouvez utiliser l'opérateur as et tester la valeur null.

MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}
2
Muad'Dib

Bien que cela n’évite pas le problème des parenthèses, il est à noter que la syntaxe la plus récente existe (à partir de C # 7) pour rendre le reste de votre code un peu plus propre:

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

Cela évite la double conversion, la vérification nulle et la disponibilité d'une variable dans les portées où elle pourrait être nulle.

1
StriplingWarrior
if (child is IContainer ? false : true)
0
Ternary