2

強く型付けされたオブジェクトのリストがあります。言うList<Activity>。それぞれActivityに、、、、、などの多くのプロパティがあります。リストは階層的です。つまりTitle、リストIdParentActivityの各アクティビティには子アクティビティがあり、各子アクティビティには独自の子アクティビティがある場合があります。ChildrenActivitiesActivityType

このリストをJSONに変換して、サードパーティのJavaScriptUIライブラリで使用できるようにする必要があります。ただし、ターゲットリストには、元のリストのプロパティのサブセット、たとえば、、Idおよびが含まれてTitleいます。

同じ条件のタイプと場所がたくさんあるので、ターゲットリストタイプを定義したくないので、強く型付けされたターゲットはありません。言い換えれば、私はクラスを持ってList<SubActivity>おらず、クラスを作成したくありませんSubActivity

この階層変換をその場で実行し、ターゲットリストからJSON文字列を取得するにはどうすればよいですか?dynamicキーワード、匿名タイプを使用することはまったく可能ですか?

アップデート:

それを想像してみてくださいActivity

public class Activity
{
    public int Id { get; set; }

    public ActivityType Type { get; set; }

    public string ActivityTitle { get; set; }

    public string Description { get; set; }

    public Activity? Parent { get; set; }

    public List<Activity> Children { get; set; }
}

そして私はこのクラスインスタンスの階層リストを持っています:

List<Activity> activities = ActivityManager.GetActivitiesHierarchically();

次に、この階層リストをJSON文字列に変換する必要がありますが、Descriptionたとえば、一部のプロパティをレンダリングする必要はありません。したがって、リストをJSONにシリアル化する前に、プロジェクション(ある種の変換)を行う必要があります。JsonActivity次のような名前のタイプを作成する場合があります。

public class JsonActivity
{
    public int id { get; set; }

    public string title { get; set; }

    public List<JsonActivity> items { get; set; }
}

しかし、このパターンはさまざまなタイプのコードの多くの場所で繰り返されているため、JsonEntityDTOを定義したくありません。

オンザフライで投影を使用して階層変換を行う方法はありますか?

4

1 に答える 1

2

C# では再帰的な匿名型を作成できないと思うので、それらを使用しようとしてもうまくいきません。

ただし、結果を JSON としてシリアル化するので、Dictionary<string, object>代わりに使用する必要があります。

ただし、ラムダは再帰的でなければなりません。それを解決するために、パラメータとして自分自身を取るラムダを書くことができます:

delegate IDictionary<string, object> RecursiveSelector<TSource>(
    RecursiveSelector<TSource> selector, TSource source);

static IEnumerable<IDictionary<string, object>> RecursiveSelect<TSource>(
    this IEnumerable<TSource> source,
    RecursiveSelector<TSource> selector)
{
    return source.Select(x => selector(selector, x));
}

次に、次のように使用できます。

List<Activity> activities = …;
var result = activities.RecursiveSelect(
    (s, a) =>
    new Dictionary<string, object>
    { 
        { "id", a.Id },
        { "title", a.ActivityTitle },
        { "children", a.Children.Select(c => s(s, c)).ToArray() }
    });
于 2012-05-08T12:16:48.300 に答える