このようなオブジェクトのリストがあります(私は.NET 3.5を使用しています)
public class MyObjects
{
public object Name { get; set; }
public bool Case { get; set; }
}
List<MyObjects> test = new List<MyObjects> {
new MyObjects { Name = "one" },
new MyObjects { Name = "two" },
new MyObjects { Name = "three" },
new MyObjects { Name = "four" },
new MyObjects { Name = "one1" },
new MyObjects { Name = "two1" },
new MyObjects { Name = "three1" },
new MyObjects { Name = "four1" },
new MyObjects { Name = "one2" },
new MyObjects { Name = "two2" },
new MyObjects { Name = "three2" },
new MyObjects { Name = "four2" },
};
次に、Linqを使用してリストを検索してみます。これは期待どおりに機能しています
var tmp = test
.Select(p => p.Name)
.Where(x => x.ToString().Contains("One", StringComparison.InvariantCultureIgnoreCase))
;
Dynamic Linqを使用すると、これも期待どおりに機能します
var dtmp = test.AsQueryable()
.Select(p => p.Name)
.Where("ToString().Contains(@0)", "one")
;
ただし、大文字と小文字を区別しないで使用しようとすると、ダイナミックが失敗します。
var dtmp2 = test.AsQueryable()
.Select(p => p.Name)
.Where("ToString().Contains(@0, @1)", "one", StringComparison.InvariantCultureIgnoreCase)
;
エラーは
No applicable method 'Contains' exists in type 'String'
私の最初の試みはこのようなContains()拡張を書くことでした
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
return source.IndexOf(toCheck, comp) >= 0;
}
Dynamic Linqが私の拡張機能を認識していないようです。 (これに従って) https://social.msdn.microsoft.com/Forums/en-US/39763339-1700-486f-9800-badd257e921e/custom-extension-methods-and-dynamic-linq-dynamic-expressionを発見しました-api?forum = linqprojectgeneral
Dynamic Linqが(静的)拡張を非常に簡単に使用できないこと。
だからどちらか:
通常の方法で拡張を変換します。しかし、どのようにしてすべてのToString()に対してこれを行うことができますか?それは可能ですか、それともMyObjectにメソッドを記述してから、特定のオブジェクトでlinqを使用する必要がありますか?
ダイナミックライブラリのコードを変更して、ハードコーディングされた(マイ)静的拡張を受け入れるようにします。
他の提案?
注:2つのダイナミクスで大文字と小文字を区別するために単純なif / elseを使用することもできますが、アプリはいくつかの複雑なフィルタリングを使用するため、動的な方法を解決することを好みます。
前もって感謝します、
アプリケーションで動的フィルター機能が必要な場合は、呼び出し元に述語を渡すことをお勧めします。
これにより、懸念事項を分離し、ユニットテストを容易にすることができます。
また、呼び出し元が述語を渡すときにIF / ELSEステートメントは必要ありません。
var predicate = new Predicate<string>(str => str.Contains("one"));
var tmp = test.Select(p => p.Name).Where(predicate);