访问C#匿名类型对象

时间:2009-04-03 11:13:24

标签: c# anonymous-types

如何在声明的范围之外访问匿名类型的对象?

例如。

void FuncB()
{
var obj = FuncA();
Console.WriteLine(obj.Name);
}

??? FuncA()
{
var a = (from e in DB.Entities
where e.Id == 1
select new {Id = e.Id, Name = e.Name}).FirstOrDefault();

return a;
}

7 个答案:

答案 0 :(得分:27)

正如其他答案所述,你真的不应该这样做。但是,如果你坚持,那么有一个令人讨厌的黑客被称为“通过示例铸造”,这将允许你这样做。在几篇文章herehere中提到了这种技术。

public void FuncB()
{
    var example = new { Id = 0, Name = string.Empty };

    var obj = CastByExample(FuncA(), example);
    Console.WriteLine(obj.Name);
}

private object FuncA()
{
    var a = from e in DB.Entities
            where e.Id == 1
            select new { Id = e.Id, Name = e.Name };

    return a.FirstOrDefault();
}

private T CastByExample<T>(object target, T example)
{
    return (T)target;
}

(虽然the author of one of those articles says that he doesn't want to be associated with it either {{3}},但我不能认可这个黑客。他的名字可能很熟悉。)

答案 1 :(得分:7)

您无法从函数返回匿名类型。

来自MSDN documentation

  

要在方法边界外传递匿名类型或包含匿名类型的集合,必须先将类型转换为object。然而,这打败了匿名类型的强类型。如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类而不是匿名类型。

答案 2 :(得分:2)

如果您使用的是.NET 4.0,则可以使用Tuples,然后返回Tuple<int, string>。您可以实现自己的2.0 / 3.5元组,实际上已有其他人已经拥有,所以如果您愿意,您应该可以这样做。

答案 3 :(得分:1)

匿名类型只是编译器生成的类,编译器不愿意告诉您类本身的名称。因此,除了返回对object的引用之外,您无法从函数返回此类的实例。

答案 4 :(得分:1)

嗯,我认为答案是:不要在声明范围之外使用匿名类型。在这种情况下,创建一个简单类型。

答案 5 :(得分:0)

会为这种情况创建一个类:

public class LISTFUNCA   
{                         
    public int identificacion;  
    public string nombre;      
}     

然后:

public List<LISTFUNCA> FuncA()   
{                                          
    var lista = (from e in DB.Entities where e.Id == 1                        
                select new { identificacion = e.Id, nombre = e.Name})
                .FirstOrDefault();  
    return lista.ToList(); 
}     

答案 6 :(得分:0)

开源框架Impromptu-Interface将允许您将匿名对象转储到接口。它具有较少hacky的优点,因为它将按照预期在程序集边界上工作。它使用轻量级代理和dlr来实现这一点。