访问C#匿名types对象

我如何访问其声明范围之外的匿名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; } 

正如其他答案所说, 你真的不应该这样做 。 但是,如果你坚持,那么就有一个被称为“以身作则”的讨厌的黑客攻击,这会让你做到这一点。 在这里和这里的几篇文章中提到了这种技术。

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

(虽然这些文章的作者说他也不想和这个文章联系起来 ,但是我不敢相信,他的名字可能是熟悉的。)

你不能从函数中返回一个匿名types。

从MSDN文档 :

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

如果你使用的是.NET 4.0,你可以使用Tuples来返回一个Tuple<int, string> 。 你可以实现你自己的Tuples 2.0 / 3.5,其他人其实已经拥有了,所以你应该可以做到这一点,如果你喜欢。

匿名types只是一个编译器生成的类,编译器不愿意告诉你类本身的名字。 因此,除了返回一个object的引用外,没有办法从一个函数中返回这个类的实例。

那么,我想答案是:不要在它声明的范围之外使用匿名types。 在这种情况下创build一个简单的types。

开源框架Impromptu-Interface将允许你将一个匿名对象转换为一个接口。 它有一个好处,就是不会因为它会像预期的那样在组装边界上工作。 它使用轻量级代理和dlr来完成此操作。

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

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