[UiPath][.NET]And/OrとAndAlso/OrElseの違い

RPA UiPath .NET
0 Comments
Tweet

Remark

This article is repost of Qiita.


前段

UiPathで”If”アクティビティを利用しているとき、複数のIfを重ねると見栄え的につらいので、なんとか出来ねーかなと調べていたところ、「AndAlso/OrElse」なるものがあることを知った。
実際に使ってみたところ、自分のケースでは効果があった。また開発の一環で非エンジニアに説明をする機会があり、その違いを簡単にまとめたのでQiitaでも書いてみようと思った。
(Flowchart使えよ、というツッコミはなしで………)

TL;DR

__上手に使えば__AndAlso/OrElseは効果的かな、と思った

それぞれの比較

And/Or

  • 結合した要素(変数、数式)を「全部」評価する
  • 要素を左側からひとつずつ評価していく過程で、全体の評価結果が確定した場合でも、問答無用で「すべて評価」する
  • 全部評価するので、要素の結合順序は問わない。要素同士の可換性がある
    • 例えば下記コードは、最終的にすべて同様の評価プロセスを経る
      • A And B And C
      • B And C And A
      • C And B And A
    • 要素ごとの評価結果によらず、全部の要素が評価されるため

AndAlso/OrElse

  • 結合した要素を「全部または一部」評価する
  • 要素を左側からひとつずつ評価していく過程で、ある要素を評価した段階で全体の評価が確定した場合、「以降の要素を評価しない」
  • 場合によって全部の要素を評価しないため、要素の結合順序の影響を受ける。要素同士の可換性はない
    • 例えば前述のコードと類似する下記コードは、いずれも評価プロセスが異なる
      • A AndAlso B AndAlso C
      • B AndAlso C AndAlso A
      • C AndAlso B AndAlso A
    • 要素ごとの評価結果およびその位置によって、評価されない要素が異なる

ケース紹介

自分が使ったのは、下記のようなコードをズボラしたとき。
datarows[]には任意のDataTableに対してselectでDataRowを抽出した結果を入れるけど、その結果がゼロである可能性がある。

if(datarows.count > 0){
    if(datarows(0).item("total") < 0){
        console.write(datarows(0)("label").toString);
    }
}

上記のようにネストされたIfを外したいときに、下記のように書くとエラーが起こる。

if(datarows.count > 0 And datarows(0).item("total") < 0){
    console.write(datarows(0)("label").toString);
}

なぜなら、結果がゼロであった場合に次のプロセスを踏むから。

  1. datarows.count > 0false を返す
  2. Andで結合しているので、上記の結果は次の要素の評価に影響しない
  3. そのためプログラムはそのままdatarows(0).item("total") < 0を評価する
  4. しかしdatarows(0)nullであり、上記の文はエラーとなる
  5. したがってifの条件判定においてエラーが発生する

これが、AndAlsoに置き換えるとどうなるか。

if(datarows.count > 0 AndAlso datarows(0).item("total") < 0){
    console.write(datarows(0)("label").toString);
}
  1. datarows.count > 0false を返す
    • datarows.count = 0)、datarows(0)nullになる
  2. AndAlsoで結合しているので、上記の結果を元に、結合された文全体を評価する
  3. すでに上記の結果でfalseが出ているため、文全体ではfalseとなることが確定している
  4. 文全体での結果が確定しているため、残りの要素は評価しない
  5. したがってdatarows(0).item("total") < 0は評価されないため、エラーとならない

  • 2018/11/26
    • コメントでのご指摘をもとに修正。