IIF の機能を強化した IF 演算子を Orcas に導入 (Sophia Salim)
私がずっと気に入っている C# と CPP の機能の 1 つは、条件演算子です。この演算子を使うと、簡潔で正確なコードを記述できます。以前のバージョンの VB.net には IIF がありましたが、これは厳密には演算子ではなく、関数呼び出しでした。Visual Studio 2008 では、この関数の "i" を取り、演算子に昇格させました。"IIF" の代わりに "IF" を使用できるようになったのです。IF 演算子は IIF 関数のすべての機能を持ちますが、ショートサーキットなど、IF 演算子独自の興味深い機能も追加されています。この演算子には、IIF 関数の機能を再現しそれをさらに強化する三項演算子の特性と、新しい種類の比較/代入を行う二項演算子の特性も備わっています。あまり漠然とした話にならないうちに、このすばらしい IF 演算子の詳しい使用方法についてご紹介します。
このブログでは、三項演算子の特性についてだけ触れます。二項演算子の特性とその他の例については、今後のブログでご紹介する予定です。
IF の最も基本的な使用目的は、条件演算子と IIF 関数の機能である、ユニバーサルな "比較、選択、および代入"です。IF の 3 つのオペランド (TestExpression、TruePart、FalsePart) の定義は次のとおりです。
-
- TestExpression とは、結果がブール値、またはブール値に変換できる値になる式のことです。式に厳密なオプションが設定され、結果がブール値であるか、または拡大変換によってブール値に変換できる値であることが必要です。
- TruePart とは、TestExpression が true に評価される場合の IF 演算子の戻り値です。演算子の戻り値の型は、TruePart の型と FalsePart の型のどちらの方がビット幅が広いかに基づいて決まります。つまり、TruePart が integer 型で FalsePart が decimal 型の場合は、幅がより広い decimal 型の戻り値になります。型変換の詳細と、型の幅の広さの一覧についてはこちらをご覧ください。
- FalsePart とは、TestExpression が false に評価される場合の IF 演算子の戻り値です。ここにショートサーキットが関連してきます。TestExpression が true に評価される場合、FalsePart は "無視" されます。コンパイラは FalsePart を処理せず、評価しません。このため、TestExpression が true である限り、ここで null 参照を行ったり、実際には存在しないオブジェクトに対して関数を呼び出したり、パーサーが許容するその他の処理を行ったりすることができます。それらは単に評価されないだけです (私は TestExpression が true である限りこのような処理も見逃されることをご説明しただけで、このような処理をお勧めしている訳ではありません)。これは、インスタンス化されていない可能性がある変数に対して関数を呼び出しているときに大変便利です。次のように記述するだけで済みます。
Dim return = If(var Is Nothing, foo1(), var.foo())
次に、IF 演算子が備える三項演算子の特性を示すコード例をお見せします。
Module Module1
Public Class Number
Private _RealPart As Double
Public Property RealPart() As Double
Get
Return _RealPart
End Get
Set(ByVal value As Double)
_RealPart = value
End Set
End Property
Private _ComplexPart As Double
Public Property ComplexPart() As Double
Get
Return _ComplexPart
End Get
Set(ByVal value As Double)
_ComplexPart = value
End Set
End Property
Public Sub New(ByVal pRealPart As Double, Optional ByVal pComplexPart As Double = 0.0)
_RealPart = pRealPart
_ComplexPart = pComplexPart
End Sub
Public Overrides Function ToString() As String
Return If(_ComplexPart = 0.0, _RealPart.ToString(), _
_RealPart.ToString & " + " & _ComplexPart.ToString() & "i")
End Function
End Class
Sub Main()
Dim i As New Number(1)
'The If operator looks checks the number to see if it is real or complex, and prints accordingly
Dim NumberPrinter = Function(arg As Number) arg.RealPart.ToString & " + " & arg.ComplexPart.ToString() & "i"
Console.WriteLine("i is a real number:")
Console.WriteLine(If(i.ComplexPart = 0.0, i.RealPart.ToString(), NumberPrinter(i)))
'Or the If operator can be moved inside the lambda to add to the elegance
Dim j As New Number(1, 2)
Dim NumberPrinter2 = Function(arg As Number) If(arg.ComplexPart = 0.0, arg.RealPart.ToString(), _
arg.RealPart.ToString & " + " & arg.ComplexPart.ToString() & "i")
Console.WriteLine("j is a complex number:")
Console.WriteLine(NumberPrinter2(j))
'You can also use the short-circuiting feature of the if operator
Dim k As Number
Console.WriteLine("k does not have any value, so we print j again:")
Console.WriteLine(If(k Is Nothing, j.ToString, k.ToString))
k = New Number(3, 4)
Console.WriteLine("And now for k with a value:")
Console.WriteLine(If(k Is Nothing, j.ToString, k.ToString))
End Sub
End Module
このコードは、k に値がないとき (最初の呼び出し時) にどのようにショートサーキットが使用されるかを示しています。null オブジェクトからのメソッド呼び出しが評価されることはありません。
IIF が大好きな方々は Orcas でも IIF 関数を使えるかどうか心配されていると思いますが、Orcas でも大丈夫、使うことができます。IIF のサポートは継続されますが、IF 演算子でこれだけの事ができるのですから、余分な "i" はもう不要ではありませんか? IF 演算子でさまざまな処理をお試しください。私も IF コードについてさらに投稿するつもりです! では、それまで。
Dim blog_next = If(bIFoundMoreInterestingScenarios, blogDelvingIntoIF, blogUnknown)
どうぞお楽しみに。
投稿 : 2008 年 3 月 11 日 10:36 PM
分類 : VB2008、Sophia Salim
VB チームの Web ログ - https://blogs.msdn.com/vbteam/archive/2008/03/11/if-operator-a-new-and-improved-iif-sophia-salim.aspx (英語) より