如何在声明的范围之外访问匿名类型的对象?
例如。
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;
}
答案 0 :(得分:27)
正如其他答案所述,你真的不应该这样做。但是,如果你坚持,那么有一个令人讨厌的黑客被称为“通过示例铸造”,这将允许你这样做。在几篇文章here和here中提到了这种技术。
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)
您无法从函数返回匿名类型。
要在方法边界外传递匿名类型或包含匿名类型的集合,必须先将类型转换为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来实现这一点。