你基本上必须使用反射。通过Type.GetProperties
不应该太难,但我不知道任何“内置”。
正如leppie指出的那样,订购并不简单 - 您必须检查参数的顺序,这些参数至少会为您提供所有类型属性的顺序。如果你只有不同的类型,那就没问题了。
如果你不关心的排序,你可以使用:
var array = t.GetType()
.GetProperties()
.Select(p => p.GetValue(t, null))
.ToArray();
编辑:我只是想的东西,这将真正修复它,但它是实现特定的。 C#编译器使用泛型类型生成匿名类型。所以new { A = 5, B = "foo" }
实际上将创建一个匿名类型是这样的:
class <>_Anon<TA, TB>
{
internal <>_Anon(TA a, TB b)
}
,因此您可以基于通用类型的一般属性,才能制定出属性的名称,然后从具体类型,以便获取属性。但它的丑陋......
using System;
using System.Linq;
using System.Reflection;
class Test
{
// Note: this uses implementation details of anonymous
// types, and is basically horrible.
static object[] ConvertAnonymousType(object value)
{
// TODO: Validation that it's really an anonymous type
Type type = value.GetType();
var genericType = type.GetGenericTypeDefinition();
var parameterTypes = genericType.GetConstructors()[0]
.GetParameters()
.Select(p => p.ParameterType)
.ToList();
var propertyNames = genericType.GetProperties()
.OrderBy(p => parameterTypes.IndexOf(p.PropertyType))
.Select(p => p.Name);
return propertyNames.Select(name => type.GetProperty(name)
.GetValue(value, null))
.ToArray();
}
static void Main()
{
var value = new { A = "a", Z = 10, C = "c" };
var array = ConvertAnonymousType(value);
foreach (var item in array)
{
Console.WriteLine(item); // "a", 10, "c"
}
}
}
字段没有隐含的顺序,所以这将如何工作? – leppie
也许你应该在这种情况下使用命名类型。 – Indy9000
你不知道。 “成员类型”和数组之间有区别。这就像在说:我如何获取'System.Windows.Forms.Form'并将其所有成员转换为'object []'。这并不是说它不可行,而是说它不是一个合适的比喻。 – CodingGorilla