4

重複の可能性:
匿名型をメソッドに渡すにはどうすればよいですか?

LINQ結果のコレクションを別のメソッドに渡したい

これはLinQコードです

var sets =
        from a in patient
        from b in patient
        from c in patient
        from d in patient
        from l in patient
        where a.VisitNum < b.VisitNum && b.VisitNum < c.VisitNum && c.VisitNum < d.VisitNum && d.VisitNum < l.VisitNum
        select new { a, b, c, d, l };

クエリは、この「組み合わせ」のような結果を示します

   ID    Visit DAte       Visit number    Rational 
    -------------------------------------------------
   a- 1     14/05/2011           1           new
   b- 1     15/06/2012           2           Emergency 
   c- 1     17/07/2012           3           Check-Up

   a- 1     14/05/2011           1           new
   b- 1     15/06/2012           2           Emergency 
   c- 1     18/12/2012           5           Check-Up
4

3 に答える 3

4

new { a, b, c, d, l }匿名型のアイテムを作成するため、LINQクエリ全体の戻り値も匿名型になります。メソッドでそのような値を渡すには、既知のタイプに変換することをお勧めします。具体的な実装からメソッドを抽象化したい場合は、新しいクラスとインターフェイスを導入するだけです。

クエリの機能とアイテムタイプが明確でないため、それに応じてクラス名とタイプ名を更新します。

interface IResultSet
{
   TypeA A { get; }
   TypeB B { get; }
   TypeC C { get; }
   TypeD D { get; }
   TypeL L { get; }
}

class ResultSet : IResultSet
{
   public ResultSet(inject all property values here) {}

   public TypeA A { get; private set; }
   public TypeB B { get; private set; }
   public TypeC C { get; private set; }
   public TypeD D { get; private set; }
   public TypeL L { get; private set; }
}

IEnumerable<IResultSet> sets =
    from a in patient
    from b in patient
    from c in patient
    from d in patient
    from l in patient
    where a.VisitNum < b.VisitNum 
          && b.VisitNum < c.VisitNum 
          && c.VisitNum < d.VisitNum 
          && d.VisitNum < l.VisitNum
    select new ResultSet(a, b, c, d, l);

また、LINQSelect()は実行を延期しているため、結果セットの列挙にアクセスするまでクエリ自体は実行されないことに注意してください。したがって、すぐに実行する必要がある場合.ToList()は、クエリの最後に呼び出しを追加するだけです。

デファード:

ProcessData(sets);

即時実行:

ProcessData(sets.ToList());

// Now you can pass results in a method like this
public void ProcessData(IEnumerable<IResultSet> items)

そして最後にdynamic、そのような匿名の型を抽象化するために型を使用しないことをお勧めします。それを使用できますが、いくつかの特別な場合には、適切な決定になります。あなたの場合、それはコードを読みにくくし、型の安全性を壊し、 DSLdynamicエンジンや動的構造データを処理するものに完全に適合しますが、OOPの基本をよく知らない人にとっては特効薬にはなりません。

于 2012-12-01T17:16:28.683 に答える
1

回避策がほとんどないため、匿名タイプを別のメソッドに直接渡すことはできません。

まず第一に、dynamicパラメータを介してそれを渡すことができます:

var at = new { a = 1, b = 2, c = 3, d = 4, l = 5 };
ProcessAnonymousType(at);

void ProcessAnonymousType(dynamic at)
{
  Console.WriteLine("Anonymous type data: {0}, {1}, {2}", at.a, at.b, at.c);
}

オブジェクトを介して匿名型のインスタンスを渡し、リフレクションを使用してプロパティにアクセスできます(実際、これは前のインスタンスと非常に似ていますが、あなたの側からより多くの努力が必要です)。

void ProcessAnonymousType(object at)
{
    // Use reflection to access a, b, c properties
}

そして、いつものように、代わりに名前付きタイプを使用できます。

于 2012-12-01T17:18:17.503 に答える
0

次のように、型付きパラメーター(および匿名型付き)を渡すことができます。

void Method<T>(T obj)
{
}

次に、リフレクションを使用して、内部に格納されているすべてのパブリックプロパティを抽出します。型指定されていない変数は、次のようにパラメーターとして渡すことができます。

var item = new { Foo = 1, Bar = "2" };
Method(item);

そして、例外はありません。リフレクションに関しては、このコード

object[] values = typeof(T)
    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
    .Select(W => W.GetValue(obj, null)).ToArray();

Methodメソッド内にアイテムのパブリックプロパティの配列を生成します。Result image

于 2012-12-01T17:31:40.350 に答える