我有这个匿名类型:
var t= new {a=1,b="lalala",c=DateTime.Now};
我怎样才能使它成为一个 Objects
数组(每个元素 -> 转换为对象)
因此类似于:
object[] v = new object[] {1,"lalala",DateTime.Now};
编辑
附注这只是一个关于学习从一种类型转换为另一种类型的知识问题。 我知道我可以从一开始就初始化一个对象数组。但这是一个学习问题。
抱歉没有提到它。
顺序很重要……为什么?原因ConstructorInfo.Invoke正在接受
Type: System.Object[] An array of values that matches the number, order (!!!) and type (under the constraints of the default binder) of the parameters for this ....
最佳答案
基本上,您必须使用反射。通过 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"
}
}
}
关于c# - 对象数组的匿名类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11212485/