0

私は次のクラスを持っています:

public class Item
{
    public Dictionary<string, string> Data
    {
        get;
        set;
    }
}

そしてそのリスト:

List<Item> items;

SQL に似た文字列を使用して、このリストを動的にフィルタリングして並べ替える必要があります。問題は、データ ディクショナリで並べ替える必要があることです。

例:Order By Data["lastname"]またはWhere Data["Name"].StartsWith("a"). 動的 linq ライブラリを使用することを考えましたが、クライアントが Data[] なしで記述できる方法はありますか? 例えば:

Name.StartsWith("abc")

それ以外の

Data["Name"].StartsWith("abc")

?

4

3 に答える 3

1

次のようなプロパティを追加できます。

public class Item
{
    public Dictionary<string, string> Data
    { get; set; }

    public string Name { get { return Data["lastname"]; } }
}
//Call by: i.Name.StartsWith("abc");

または拡張メソッド:

public static class ItemExtensions 
{
  public static string Name(this Item item)
  {
    return item.Data["lastname"];
  }
}
//Call by: i.Name().StartsWith("abc");

または、非常に一般的に使用される方法である場合は、次のようなものを追加できます.NameStartsWith()

public static string NameStartsWith(this Item item, stirng start)
{
  return item.Data["lastname"].StartsWith(start);
}
//Call by: i.NameStartsWith("abc");
于 2010-03-28T14:27:17.577 に答える
1

これは、Linq Dynamic Query ユニットとは関係ありません。そのユニットは、実際のフィールド/プロパティがあり、それらの名前が実行時に与えられる場合のためのものです。つまり、次のようなクラスがあります。

public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

そして、次のようなクエリを記述できるようにしたいと考えています。

var sortedPeople = people.OrderBy("FirstName");

これとは正反対のことをしようとしています。実際のプロパティを持たず、属性辞書だけを持つクラスがあり、コンパイル時の安全性が必要です。あなたはそれを持つことができません。特に辞書が公開されていて、誰でも辞書に直接追加/削除できる場合は、アイテムが辞書にあることを保証する方法はありません!

その特定のクラス設計を使用しなければならない何らかの理由がある場合は、Nick が提示したようにいくつかのラッパーを作成することも考えられますが、気にする必要はありませんData。全世界。代わりに、単一の安全なゲッター メソッドまたはインデクサー プロパティを提供し、そこにあると予想されるプロパティの名前でいくつかの定数 (または列挙型) を作成します。

public class Item
{
    public Dictionary<string, string> Data { get; set; }

    public string GetValue(string key)
    {
        if (Data == null)
            return null;
        string result;
        Data.TryGetValue(key, out result);
        return result;
    }
}

public class ItemKeys
{
    public const string Name = "Name";
    public const string Foo = "Foo";
}

等々。実際にItemKeysはそれほど重要ではありません。安全なGetValue方法が重要です。そうしないと、NullReferenceExceptionifDataが割り当てられていないか、KeyNotFoundException1つのItemインスタンスでもそのプロパティがない場合にリスクが生じるためです。ここでメソッドを使用すると、GetValue何があっても成功します。

var myItems = items.OrderBy(i => i.GetValue(ItemKeys.Name));

同じ属性に対して多くの繰り返しコードを書いていることがわかった場合は、ショートカット プロパティまたは拡張メソッドをクラスに追加することについて心配し始めます

于 2010-03-28T14:54:18.853 に答える
0

コンパイル時にプロパティの名前を知らないと仮定します (この場合、単にプロパティを定義するだけで、この問題は発生しません)。試すことができる 2 つの提案がありますが、自分で実装したわけではないので、うまくいくとは限りません。

  • .NET 4.0 を使用できる場合は、メソッド (として宣言されているオブジェクトで使用すると呼び出される) を継承しDynamicObjectて実装できます。動的 LINQ が DLR で動作すると仮定すると、 から継承するオブジェクトに対してこのメ​​ソッドを自動的に呼び出す必要があります。メソッド内で、アクセスしたプロパティの名前を取得するため、辞書検索を実行できます。(ただし、このソリューションは、Dynamic LINQ が DLR とうまく統合されている場合にのみ機能します)。TryGetMembero.FoodynamicDynamicObjectTryGetMember

  • いずれにせよ、ユーザーが入力した文字列の基本的な解析を実行し、NameたとえばData["Name"]. これは間違いなく機能しますが、少し難しいかもしれません (文字列定数内ではなく、正しいコンテキストで置換を行っていることを少なくとも確認する必要があるため)。

拡張メソッドについて - Dynamic LINQ が拡張メソッドを処理するかどうかはわかりません (ただし、参照されているすべてのアセンブリを検索する必要があるため、そうは思いません)。

于 2010-03-28T14:35:16.167 に答える