【问题标题】:Generic property getter in LinqLinq 中的通用属性获取器
【发布时间】:2010-11-10 07:53:09
【问题描述】:

我有一个层次集合对象,我试图在 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();
}

这很有效。目前我已经制作了返回测试对象并访问调用方法中的属性的方法。但想知道我是否可以实现通用属性获取器。

编辑:

Class Hierarcy{
  public IList<Level1> level1;
}

Class Level1 {
public IList<Test> test;
}

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

【问题讨论】:

  • 我已经读了 5 遍了,仍然不明白你在做什么......
  • 您没有提供足够的详细信息。你的“层次结构”是如何组织的? Level1 的类型是什么?如果有一个名为Level2Level3 的子属性,那是什么类型? “最后一级”是什么意思?
  • hierarchyObject 有一个 Level1 的集合,其中有一个 Test 的集合
  • 为什么在where子句中使用Test.ID.Equals(ID)Test的类成员),而不是test.ID.Equals(ID)(局部变量test的实例成员)?
  • 抱歉,打错字了,应该是 test.ID.Equals(ID)

标签: .net linq .net-3.5


【解决方案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;

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

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));
}

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

【讨论】:

    【解决方案2】:

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

    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();
    }
    

    【讨论】:

      【解决方案3】:

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

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

      现在没有电脑测试。

      同样在方法中,您应该根据选择器将整个方法声明为泛型(相同的泛型参数)或使用public static TResult GetTest&lt;TResult&gt; (.. , Func&lt;Test, TResult&gt; selector)

      【讨论】:

      • 他不能只做select selector(test)吗?
      • 因为在您的情况下它创建了新方法,它只是调用选择器方法。就我而言,您是使用选择器方法直接调用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 2012-09-04
      • 2021-11-23
      相关资源
      最近更新 更多