我有这个班:
public class allFields
{
public string EAN { get; set; }
public string title { get; set; }
public string qty { get; set; }
public string price { get; set; }
public DateTime date { get; set; }
}
返回匿名类型的函数:
public IEnumerable<object> stockEtatQty()
{
List<allFields> afList = new List<allFields>();
var query = from x in ctx.book
where x.qty > 0
select x;
foreach (var item in query)
{
allFields af = new allFields();
af.EAN = item.EAN;
af.title = item.Titre;
af.qty = ""+item.Quantite;
afList.Add(af);
}
var q = from x in afList
select new { EAN=x.EAN, Title=x.title, Quantity=x.qty };
return q; //q is a IEnumerable<'a> where a is new {string EAN, string Title, string Quantity}
}
在我的WinForm中,使用以下函数:
private void QuantityToolStripMenuItem_Click(object sender, EventArgs e)
{
ServiceStock sstock = new ServiceStock();
var q = sstock.stockEtatQty().ToList();// q is a list<object>
string str = "";
foreach (var item in q)
{
str += item + Environment.NewLine;
}
MessageBox.Show(str);
}
结果是:
{ EAN = 1, Title = CSharp Security, Quantity = 970 }
{ EAN = 2, Title = MISC, Quantity = 100 }
...
我想要什么?
我想要不喜欢上面的结果,但要将循环item
中的foreach
的每个字段分开,例如获取item.EAN
,item.Title
和item.Quantity
。< / p>
如果我的问题没有解决方案,我想知道一个替代方案,
谢谢你的帮助。
答案 0 :(得分:2)
显而易见的解决方案是创建自定义类型(让我们称之为BookInfo
)并返回IEnumerable<BookInfo>
而不是IEnumerable<object>
(如果您需要,可以覆盖ToString
将格式放入此类本身)。
然后您可以轻松格式化输出。
public class BookInfo
{
public string EAN {get;set;}
public string Title {get;set;}
public int Quantity {get;set;}
}
public IEnumerable<BookInfo> stockEtatQty()
{
...
var q = from x in afList
select new BookInfo { EAN=x.EAN, Title=x.title, Quantity=x.qty };
return q;
}
private void QuantityToolStripMenuItem_Click(object sender, EventArgs e)
{
ServiceStock sstock = new ServiceStock();
var q = sstock.stockEtatQty();
var message = string.Join(Environment.NewLine,
q.Select(item => String.Format("{0} {1} {2}", item.EAN, item.Title, item.Quantity)));
MessageBox.Show(message);
}
答案 1 :(得分:1)
由于在您退出stockEtatQty()
方法时,有关匿名类型对象的静态类型信息会丢失,您可以将对象强制转换为dynamic
并访问如下字段:
str = string.Join(Environment.NewLine, q.Cast<dynamic>().Select(item =>
string.Format("{0} {1} {2}", item.EAN, item.Title, item.Quantity)
));
转换为dynamic
告诉编译器需要在运行时解析EAN
,Title
和Quantity
。
请注意,我还通过调用foreach
替换了string.Join
循环以提高性能:重复的字符串连接会创建不必要的部分字符串对象,string.Join
会避免这种情况。另一种解决方案是使用StringBuider
而不是字符串连接+=
。
stockEtatQty
在项目(服务)中,QuantityToolStripMenuItem_Click
在另一个项目中(查看)
不幸的是,这意味着您将无法使用匿名类型:使用内部可见性生成匿名类型,将其使用限制在生成它们的程序集中。您可以根据this answer中描述的ExpandoObject
使用变通方法
var q = afList.Select(x => {
dynamic res = new ExpandoObject();
res.EAN=x.EAN;
res.Title=x.title;
res.Quantity=x.qty;
return res;
});
答案 2 :(得分:0)
您可以使用动态对象集合而不是简单对象作为方法的返回类型:
public IEnumerable<dynamic> stockEtatQty()
然后您将没有IntelliSense,但在运行时将找到属性:
foreach (var item in sstock.stockEtatQty())
str += String.Format("{0}", item.EAN) + Environment.NewLine;
但我建议您使用EAN,Title和Quantity属性创建自定义类。或者只使用您的allFields
而不是匿名对象。
还要考虑使用StringBuilder进行字符串创建,以避免创建大量的内存中字符串:
var builder = new StringBuilder();
foreach (var item in sstock.stockEtatQty())
builder.AppendFormat("{0}{1}", item.EAN, Environment.NewLine);
MessageBox.Show(builder.ToString());
答案 3 :(得分:0)
创建一个表示新对象结构的新类并返回该对象。
var q = from x in afList
select new SmallerType { EAN=x.EAN, Title=x.title, Quantity=x.qty };
WinForm功能
foreach (SmallerType item in q)
{
//
}