Fáb*_*nes 9 .net c# anonymous-types
我们多少次声明一个简单的类或结构来保存一些属性,仅在方法返回时使用它们一次.我想太多次了,幸好我们总是有匿名对象,可以在运行时声明到位.
考虑到这个想法,我想知道如何声明这样一个匿名对象的数组.
例:
var Employee = new { ID = 5, Name= "Prashant" };
Run Code Online (Sandbox Code Playgroud)
这创建了一个具有两个属性的匿名对象,一个是整数,另一个是字符串.
这里一切都很好,但是我应该如何声明这种对象的数组,以及如何建议使用a for和foreach循环迭代它.
该foreach循环是真的,我认为这个问题,因为foreach循环期待一个声明的类型.如果有的话,我当然也会知道它.
Eri*_*ert 20
我们多少次声明一个简单的类或结构来保存一些属性,仅在方法返回时使用它们一次.我想太多次了,幸好我们总是有匿名对象,可以在运行时声明到位.
你的第一句和第二句表明你有相反的目的.匿名类型以及匿名类型的数组不能轻易地从方法返回,因为无法声明返回类型.尝试仅对临时局部变量使用匿名类型.
考虑到这个想法,我想知道如何声明这样一个匿名对象的数组.
像这样:
var array = new[]
{
new { X = 123, Y = 456 },
new { X = 345, Y = 567 }
};
Run Code Online (Sandbox Code Playgroud)
您如何建议使用for和foreach循环迭代它.
foreach(var item in array)
...
Run Code Online (Sandbox Code Playgroud)
要么
for (int i = 0; i < array.Length; i += 1)
{
var item = array[i];
...
}
Run Code Online (Sandbox Code Playgroud)
[编辑 - 更新以显示人口、基本枚举等]
正如@Eve 所说,LINQ 是您的朋友;作为一般经验法则,不要尝试传递匿名类型 -如果你很聪明,你可以- 但是在它们声明的上下文/范围之外处理它们是一个巨大的痛苦。
简而言之,我决定看看人们可以通过什么方式“声明一个匿名类型的数组”作为一个有趣的思想实验,并提出了这些:
(注意:“转储”是由于这是用 LINQPad 编写的)
// Our anonymous type sequence
var anonymousEnumerable = Enumerable
.Range(0, 10)
.Select(i => new { ID = i, Text = i.ToString() });
var enumerableCount = anonymousEnumerable.Count();
var anonymousType = anonymousEnumerable.First().GetType();
// Option #1 - declare it as dynamic, i.e., anything goes
dynamic[] asDynamicArray = new dynamic[enumerableCount];
foreach(var tuple in anonymousEnumerable.Select((item, i) => Tuple.Create(i, item)))
{
asDynamicArray[tuple.Item1] = tuple.Item2;
}
// Let's go the IEnumerable route
foreach (var asDynamic in asDynamicArray)
{
Console.WriteLine("ID:{0} Text:{1}", asDynamic.ID, asDynamic.Text);
}
// Lowest common denominator: *everything* is an object
object[] asObjectArray = new object[enumerableCount];
foreach(var tuple in anonymousEnumerable.Select((item, i) => Tuple.Create(i, item)))
{
asObjectArray[tuple.Item1] = tuple.Item2;
}
// Let's iterate with a for loop - BUT, it's now "untyped", so things get nasty
var idGetterMethod = anonymousType.GetMethod("get_ID");
var textGetterMethod = anonymousType.GetMethod("get_Text");
for(int i=0;i < asObjectArray.Length; i++)
{
var asObject = asObjectArray[i];
var id = (int)idGetterMethod.Invoke(asObject, null);
var text = (string)textGetterMethod.Invoke(asObject, null);
Console.WriteLine("ID:{0} Text:{1}", id, text);
}
// This is cheating :)
var letTheCompilerDecide = anonymousEnumerable.ToArray();
foreach (var item in letTheCompilerDecide)
{
Console.WriteLine("ID:{0} Text:{1}", item.ID, item.Text);
}
// Use reflection to "make" an array of the anonymous type
var anonymousArrayType = anonymousType.MakeArrayType();
var reflectIt = Activator.CreateInstance(
anonymousArrayType,
enumerableCount) as Array;
Array.Copy(anonymousEnumerable.ToArray(), reflectIt, enumerableCount);
// We're kind of in the same boat as the object array here, since we
// don't really know what the underlying item type is
for(int i=0;i < reflectIt.Length; i++)
{
var asObject = reflectIt.GetValue(i);
var id = (int)idGetterMethod.Invoke(asObject, null);
var text = (string)textGetterMethod.Invoke(asObject, null);
Console.WriteLine("ID:{0} Text:{1}", id, text);
}
Run Code Online (Sandbox Code Playgroud)