Linq的通用属性getter

时间:2010-11-10 07:53:09

标签: .net linq .net-3.5

我有一个层次结构集合对象,我试图在Linq中检索最后一个级别对象的属性。我不想为每个属性编写一个get方法。不知道如何通过选择器

实现它
Class Test {
    public int ID { get; set; }
    public int PopertyA { get; set; }
    public string PopertyB { get; set; }
              ...Many more properties

}

public static TResult GetTest(hierarchyObject, int ID, Func<TSource, TResult> selector)
{
    return (from level1 in hierarchyObject.Level1
            from test in level1.Test
            where test.ID.Equals(ID)
            select selector).First();
}

这个工作。目前我已经使方法返回测试对象并访问调用方法中的属性。但是想知道我是否可以实现通用属性getter。

修改

Class Hierarcy{
  public IList<Level1> level1;
}

Class Level1 {
public IList<Test> test;
}

给定一个层次对象和test.ID,我想检索Test的任何属性。

3 个答案:

答案 0 :(得分:1)

这取决于您想要对您的财产做什么。为了避免为您感兴趣的每个属性重复整个LINQ查询,最好首先获取Test对象,然后检查其各自的属性:

class Hierarcy
{
   public IList<Level1> Level1;
   public Test GetTest(int ID)
   {
       return this
          .Level1
          .SelectMany(level => level.Test)
          .Where(test => test.ID == ID)
          .First();
   }
}

获得Test课程后,您将拥有其所有属性:

Test t = myHierarchy.GetTest(someId);

// do something
int i = test.PropertyA;
string s = text.PropertyB;

如果您有兴趣动态获取属性的值,仅使用其名称,则可以使用Reflection进行:

Test t = myHierarchy.GetTest(someId);

// this will print all properties and their values
foreach (PropertyInfo pi in t.GetType().GetProperties())
{
    Console.WriteLine("Name:{0}, Value:{1}",
       pi.Name,
       pi.GetValue(pi, null));
}

在这两个示例中,实际查询只执行一次,如果集合中有很多对象,这可能很重要。

答案 1 :(得分:1)

我想你可能想要这样的东西:

public static TResult GetTest(hierarchyObject, int ID, Func<Test, TResult> selector)
{
    return (from level1 in hierarchyObject.Level1
            from test in level1.Test
            where test.ID.Equals(ID)
            select selector(test)).First();
}

答案 2 :(得分:0)

您必须使用方法链。你不能使用查询表达式。至少对于选择部分。休息可以保留为查询表达式。

hiearchyObject.Level1.SelectMany(x=>x.Test).Where(test=>test.ID.Equals(ID)).Select(selector).First();

现在没有PC来测试它。

同样在方法中,您应该将整个方法声明为选择器的通用(相同的通用参数)或使用public static TResult GetTest<TResult> (.. , Func<Test, TResult> selector)