【问题标题】:How to return Anonymous Type while using Linq [duplicate]如何在使用 Linq 时返回匿名类型 [重复]
【发布时间】:2011-03-10 02:49:34
【问题描述】:

可能重复:
LINQ to SQL: Return anonymous type?

有谁知道如何返回匿名类型。我正在使用 Linq,我需要返回以下代码

private <What's the return type to be provided here> SampleLinq(Int32 Num)
    {
        var query = (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId });
        return (query)       

    }

【问题讨论】:

标签: c# asp.net linq anonymous-types


【解决方案1】:

很抱歉,您不能在方法范围之外返回匿名类型。

这是获取匿名类型的另一种方法

// Method that returns anonymous type as object
object ReturnAnonymous()
{
  return new { City="Prague", Name="Tomas" };
}

// Application entry-point
void Main()
{
  // Get instance of anonymous type with 'City' and 'Name' properties
  object o = ReturnAnonymous();

  // This call to 'Cast' method converts first parameter (object) to the
  // same type as the type of second parameter - which is in this case 
  // anonymous type with 'City' and 'Name' properties
  var typed = Cast(o, new { City="", Name="" });
  Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City);
}

// Cast method - thanks to type inference when calling methods it 
// is possible to cast object to type without knowing the type name
T Cast<T>(object obj, T type)
{
  return (T)obj;
}

您只能将它用于一个程序集中的类型(来自两个不同程序集的两个匿名类型将在内部编译为无法使用此技巧转换的两种不同类型)。

【讨论】:

    【解决方案2】:

    返回动态类型:

          public static dynamic  getCustomer() 
    { 
        ..... 
        var x = from c in customers 
                select new {Fname = c.FirstName}; 
    
        return x; 
    } 
    
    static void Main(string[] args) 
    { 
        dynamic x = getCustomer(); 
        Console.WriteLine(Enumerable.First(x).Fname); 
        Console.ReadKey(); 
    } 
    

    【讨论】:

      【解决方案3】:

      你不能那样做。这就是它被称为匿名的原因。它没有名字。但您始终可以将其转换为 object

      【讨论】:

        【解决方案4】:

        好吧,你实际上不能那样做,但here's a hack 就在这方面。

        【讨论】:

        • 如果您提供的链接失效,最好至少添加一个简短的黑客描述。
        【解决方案5】:
        private object SampleLinq(Int32 Num)
        {
        return (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId });
        }
        

        【讨论】:

        • 但是如何将对象重新转换为 var 以获取属性,因为对象不包含 getenumerator 的公共定义?
        • 如果没有其他方向,例如 FirstOrDefault(),查询将返回一个 IEnumerable。然后你必须使用反射来弄清楚如何使用它。
        • @renjithmaxy - "var" != ""。 var 在编译时仍然是强类型的。
        【解决方案6】:

        您不能从方法中返回匿名类型。

        您可以创建一个简单的类来包装匿名类型,但您仍然需要一个类(或强制转换为object)。

        但请记住,如果您转换为 object,则无法进行回退。您需要反射来读取任何数据。

        【讨论】:

          【解决方案7】:

          您从 hack 中看到的答案是通过方法边界获取匿名类型的大量工作。你不应该这样做。如果您需要从方法中传回某些内容,则应该传递具体类型。

          【讨论】:

          • @Mathew - 一般来说我会同意你的观点,但在数据绑定的情况下,目标属性(例如 DataContext)无论如何只是类型对象,并且绑定直到运行时才真正绑定。因此,例如,返回一个 IEnumerable 可能很有用,该 IEnumerable 枚举匿名类型的实例,这些实例的作用类似于给定集合的只读包装器/视图模型。所以在某些情况下,我认为允许返回匿名类型的实例可能是有意义的。
          • @jpierson - 当然,我认为规则总有例外。我希望在这种情况下,它可能是其中之一,但是在您尝试在代码中访问这些成员的情况下,是时候从匿名实例切换到静态类型实例了。
          • @Mathew - 同意,就像您在代码中使用反射只是为了获取值一样。可能有一小部分示例可能是合法的,但否则您实际上是在尝试使用静态类型语言进行动态编程。现在有了 dynamic 关键字,我可以看到一些 C# 开发人员在使用动态样式编程时可能会开始有些古怪,但过度使用它很快就会与使用 C# 等强类型语言的好处产生不必要的分歧。
          【解决方案8】:

          这取决于您希望如何处理返回值。

          • 如果您要在 UI 中绑定它 你可以重新运行 IEnumerableIQueryable

          • 如果您要对返回值使用反射,只需返回类型对象

          • 如果您使用 c# 4.0,您可以返回一个 动态类型

          • 如果您使用 EFLinq to SQL 进一步加入由您的匿名类型组成的查询,您 可以改为创建一个具体的类,并且 使用具体的占位符 技术。有关此的更多详细信息 我可以提供一些帮助。

          正如其他人所提到的,您真的应该质疑从方法返回匿名类型是否是解决手头问题的最佳方法。一般来说,通常有更好的基于模式的方法,它可能需要更多的预先编码,但可能会产生更优雅的设计。话虽如此,我确实相信在某些合法的情况下,例如数据绑定,返回匿名类型实例是完全可以接受的。

          更新: 我只是想分享一个感兴趣的花絮,以防那些阅读者不知道。匿名类型根据它们的属性名称和类型是唯一的,因此假设您在两者中都有方法 A 和方法 B,您可以通过执行以下代码来创建一个匿名类型,该类型具有一个名为 Name 的单个字符串类型属性。

          public object A()
          {
              return new { Name = "Cid" }
          }
          
          public object B()
          {
              return new { Name = "Galuf" }
          }
          
          public void Test()
          {
             System.Diagnostics.Trace.Assert(A().GetType() == B().GetType());
          }
          

          现在,即使此类型是在两个不同的位置定义的,编译器也只会创建一个共享类型,因为它们都具有由属性类型和属性名称定义的相同属性集。在这方面,属性可以被认为是匿名类型的一种签名。使用这些知识,可以使用不同的技术对匿名类型实例进行自省,这些实例已被强制转换为对象或使用 dynamic 关键字延迟。通过使用泛型方法也有一些很好的方法来处理匿名类型,就像 Linq 使用静态 Enumerable 和 Queryable 类中的方法一样。通过这种方式,您可以在不使用反射的情况下创建任何给定匿名类型的新实例。诀窍是您必须使用匿名类型的实例来传递给方法,以便让泛型方法推断出类型。如果有人对这些主题进一步感兴趣,因为它们适用于原始海报问题,请发表评论,我可以尝试澄清其中一些技术。

          【讨论】:

          • 真的!没有 cmets 解释否决票?
          • +1 我从来不知道这些类型可以相等!否决票可能是因为您的 The trick is though that you have to use an instance of the anonymous type to pass to methods in order to have the type be inferred by the generic method. If anybody is interested in these topics further as they apply to the original posters question, leave a comment and I can try to clarify some of these techniques. 而不是写它是什么。
          猜你喜欢
          • 1970-01-01
          • 2011-05-21
          • 1970-01-01
          • 2012-04-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多