c# - 如何反序列化通用列表当我不知道(T)的类型时?
出于听觉原因,我使用二进制格式化程序将业务方法的参数序列化到数据库中。
问题是,当参数是通用列表时,我找不到转换反序列化对象的方法,因为我不知道类型,或者如果我知道类型,我不知道如何转换对象运行时。
有人知道如何在运行时动态地转换包含通用列表的对象吗?
我需要这样做,因为我需要在属性网格中显示反序列化的数据:
object objArg = bformatter.Deserialize(memStr);
//If the type is a clr type (int, string, etc)
if (objArg.GetType().Module.Name == "mscorlib.dll")
{
//If the type is a generic type (List<>, etc)
//(I'm only use List for these cases)
if (objArg.GetType().IsGenericType)
{
// here is the problem
pgArgsIn.SelectedObject = new { Value = objArg};
//In the previous line I need to do something like...
//new { Value = (List<objArg.GetYpe()>) objArg};
}
else
{
pgArgsIn.SelectedObject = new { Value = objArg.ToString() };
}
}
else
{
//An entity object
pgArgsIn.SelectedObject = objArg;
}
for auditory reasons I stores the arguments of the business methods serialized into the database using the binaryformatter.
The problem is that when an argument is a generic list I don't find the way to cast the deserialized object because I don't know the type, or If I will know the type I don't know how to cast the object at runtime.
Anybody knows how to cast an object containing a generic list dinamically at runtime?
I need to do this because I need to show the deserialized data in a property grid:
object objArg = bformatter.Deserialize(memStr);
//If the type is a clr type (int, string, etc)
if (objArg.GetType().Module.Name == "mscorlib.dll")
{
//If the type is a generic type (List<>, etc)
//(I'm only use List for these cases)
if (objArg.GetType().IsGenericType)
{
// here is the problem
pgArgsIn.SelectedObject = new { Value = objArg};
//In the previous line I need to do something like...
//new { Value = (List<objArg.GetYpe()>) objArg};
}
else
{
pgArgsIn.SelectedObject = new { Value = objArg.ToString() };
}
}
else
{
//An entity object
pgArgsIn.SelectedObject = objArg;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用
BinaryFormatter
,您不需要知道类型;元数据包含在流中(使其更大,但是嘿!)。但是,除非您知道类型,否则无法强制转换。通常在这种情况下,您必须使用常见的已知接口(非通用IList
等)和反射。还有很多。我也想不出知道在
PropertyGrid
中显示的类型的巨大要求 - 因为它接受object
,只需给它BinaryFormatter
> 提供。您在那里看到了一个具体问题吗?同样,您可能想要检查IList
(非泛型) - 但不值得担心IList
,因为这不是>PropertyGrid
检查!当然,如果您愿意的话,您可以找到
T
(像这样) - 并使用MakeGenericType()
和Activator.CreateInstance
- 不太漂亮。好的;这是一种使用自定义描述符的方法,不涉及了解有关对象或列表类型的任何信息;如果您确实想要,可以将列表项直接扩展到属性中,因此在本例中您会看到 2 个假属性(“Fred”和“Wilma”) - 这是额外的工作,虽然;-p
With
BinaryFormatter
you don't need to know the type; the metadata is included in the stream (making it bigger, but hey!). However, you can't cast unless you know the type. Often in this scenario you have to use common known interfaces (non-genericIList
etc) and reflection. And lots of it.I also can't think of a huge requirement to know the type to show in a
PropertyGrid
- since this acceptsobject
, just give it whatBinaryFormatter
provides. Is there a specific issue you are seeing there? Again, you might want to check forIList
(non-generic) - but it isn't worth worrying aboutIList<T>
, since this isn't whatPropertyGrid
checks for!You can of course find the
T
if you want (like so) - and useMakeGenericType()
andActivator.CreateInstance
- not pretty.OK; here's a way using custom descriptors that doesn't involve knowing anything about the object or the list type; if you really want it is possible to expand the list items directly into the properties, so in this example you'd see 2 fake properties ("Fred" and "Wilma") - that is extra work, though ;-p
如果您使用的序列化程序不保留类型 - 至少,您必须将
T
的类型与数据一起存储,并使用它来反射性地创建通用列表:现在您有了
listType
,这正是您使用的List
(例如List
)。您可以将该类型传递到反序列化例程中。If the serializer you are using does not retain the type - at the least, you must store the type of
T
along with the data, and use that to create the generic list reflectively:Now you have
listType
, which is the exactList<T>
you used (say,List<Foo>
). You can pass that type into your deserialization routine.