[解決済み] Stringを同等のLINQ Expression Treeに変換する方法は?
2022-04-15 10:54:42
質問
これは、元の問題の簡略版である。
Personというクラスがあります。
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
...そして、インスタンスとしましょう。
var bob = new Person {
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = '1/1/2000'
}
として、以下のように書きたいと思います。 文字列 をお気に入りのテキストエディターで表示させたいのですが・・・。
(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3
この文字列と私のオブジェクト・インスタンスを受け取って、TRUEまたはFALSEを評価したいのです。
以下は、現在の私の考えです。
- 基本的な比較演算子と論理演算子をサポートするために、ANTLRに基本的な文法を実装する。Visual Basicのプリケーションと機能セットの一部をここにコピーしようと考えている。 http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx
- ANTLRに、与えられた文字列から適切なASTを作成させる。
- ASTをウォークして 述語ビルダー フレームワークを使用して、Func<Person, bool>を動的に作成します。
- 必要に応じて、Personのインスタンスに対して述語を評価する。
質問ですが、私はこれを完全に焼きすぎてしまったのでしょうか?
EDIT: 選択された解決策
Dynamic Linq Library、特にLINQSamplesで提供されているDynamic Queryクラスを使用することにしました。
以下、コードです。
using System;
using System.Linq.Expressions;
using System.Linq.Dynamic;
namespace ExpressionParser
{
class Program
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Weight { get; set; }
public DateTime FavouriteDay { get; set; }
}
static void Main()
{
const string exp = @"(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3";
var p = Expression.Parameter(typeof(Person), "Person");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, exp);
var bob = new Person
{
Name = "Bob",
Age = 30,
Weight = 213,
FavouriteDay = new DateTime(2000,1,1)
};
var result = e.Compile().DynamicInvoke(bob);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
Result は System.Boolean 型であり、この例では TRUE です。
Marc Gravellに感謝します。
含まれるもの システム.Linq.Dynamic nuget パッケージ、ドキュメント こちら
解決方法は?
を使用することはできますか?
動的 linq ライブラリ
ということです。特に、私が考えているのは
Where
節があります。必要であれば、リスト/配列の中に入れて、ちょうど
.Where(string)
を追加してください。
var people = new List<Person> { person };
int match = people.Where(filter).Any();
そうでない場合は、パーサーを書くことで (
Expression
私は、クリスマス前の電車通勤中に似たようなものを書きました(ソースは持っていないと思いますが)。
関連
-
[解決済み】パディングが無効で、削除できない?
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み] base64文字列をエンコード、デコードするにはどうしたらいいですか?
-
[解決済み] UTF-8 byte[]を文字列に変換する方法
-
[解決済み] intからstringに変換しますか?
-
[解決済み】C#で文字列をenumに変換する
-
[解決済み】文字列の中にある文字列(実際はchar)の出現回数を数えるには?
-
[解決済み】StringをIntに変換する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】Visual studio 2019がデバッグ時にフリーズする件
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み] 2つのリストを結合する
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み] InvokeとDynamicInvokeの違いについて