我想将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
答案 0 :(得分:4)
new { a, b, c, d, l }
创建一个anonymous type项,因此整个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);
请记住,LINQ Select()
已经确定了执行,因此在您访问结果集枚举之前,查询本身不会被执行,因此如果您需要立即执行它,只需在查询中添加.ToList()
调用端:
递延:
ProcessData(sets);
立即执行:
ProcessData(sets.ToList());
// Now you can pass results in a method like this
public void ProcessData(IEnumerable<IResultSet> items)
最后我建议不要使用dynamic
类型来抽象这样的匿名类型,你可以使用它,但在某些特殊情况下,这将是充分的决定。在你的情况下,它会降低代码的可读性并破坏类型安全性,dynamic
完全适合DSL引擎和处理动态结构数据的东西,但对于那些非常了解OOP基础知识的人来说不是银弹。
答案 1 :(得分: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
}
而且,与往常一样,您可以使用命名类型。
答案 2 :(得分: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