49

式ツリーに取り組んでいるライブラリがあります。ライブラリは C# と VB.Net の両方で動作する必要があります

式ツリーの構築方法に関する言語間のいくつかの違いに気付きました

  • 文字列比較は次のように
    () => "a" == "b"なりExpression.Equals("a", "b")
    Function() "a" = "b"ますExpression.Equals(Expression.Call(CompareString, "a", "b"), 0)
    (VB.Net がここで CompareString を使用する理由を理解しています)

  • 文字列の連結は次の
    () => "a" + "b"ようになりExpression.Add("a", "b", String.Concat)
    Function() "a" & "b"ますExpression.Call(String.Concat, "a", "b")

  • 最適化?
    () => !(1 == 2)なるExpression.Not(Expression.Equals(1, 2))
    Function() Not (1 = 2)_Expression.NotEqual(1, 2)

私のライブラリはこれらすべての違いを処理しますが、注意が必要な違いは他にありますか?

編集 私のコードが何をするかについての説明。

私が使用しているシステムには、次のように指定するドキュメントのフィルターがあります。

var filter = document.Filter;
filter.LeftParanthesis();
filter.Column(columnNumber);
filter.Equals();
filter.Value("abc");
filter.RightParanthesis();
filter.And();
filter.LeftParanthesis();
...
document.Refresh();

フィルターを使いやすくするために、私のコードでは、フィルターをExpression<Func<bool>>ラムダとして指定できます。

Expression<Func<bool>> filter = () => (123.AsStringColumn() == "abc") && (...);
filter.Apply(document);

次に、私のコードは式ツリーを反復し、上記で指定したドキュメント フィルター メソッドを呼び出します。フィルターは、ラムダに入れることができるすべてのものをサポートしているわけではありません。メソッド呼び出しは最も明白なものです。

VB.Net は、C# が生成しない場合にメソッド呼び出しを生成するため、これらをインターセプトして別の方法で処理する必要があります。

4

2 に答える 2

6

除算演算子は/、C# と VB では動作が異なります。C# では、使用されるデータ型に適応しますが、VB は常にオペランドを浮動小数点値に変換します。

() => 1 / 2なるExpression.Divide(1, 2)
Function() 1 / 2_Expression.Divide(Expression.Convert(1, Double), Expression.Convert(2, Double))

\VB では、整数除算と浮動小数点除算に演算子を使用して、C#/の演算子と同じものを取得する必要があります。/

于 2013-05-05T08:37:49.447 に答える
2

私は自分のプロジェクトに頻繁に関連する C# と VB.Net を使用する必要があり、VB.Net がアンセーフ モードのときに見たほとんどの違いがありました。つまり、VB.Net をタイプセーフにすると (Option strict on、option explicite on...option all on)、C# のように動作します。

于 2013-05-10T14:06:42.660 に答える