gpt4 book ai didi

c# - 当我不知道 (T) 的类型时如何反序列化通用列表

转载 作者:太空狗 更新时间:2023-10-29 23:19:24 25 4
gpt4 key购买 nike

出于听觉原因,我使用二进制格式化程序将序列化的业务方法的参数存储到数据库中。

问题是,当参数是通用列表时,我找不到转换反序列化对象的方法,因为我不知道类型,或者如果我知道类型我不知道如何转换运行时的对象。

有人知道如何在运行时动态转换包含泛型列表的对象吗?

我需要这样做,因为我需要在属性网格中显示反序列化的数据:

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;
}

最佳答案

BinaryFormatter不需要知道类型;元数据包含在流中(让它变大,但是嘿!)。但是,除非您知道类型,否则您不能强制转换。通常在这种情况下,您必须使用常见的已知接口(interface)(非通用 IList 等)和反射。还有很多。

我也想不出一个巨大的要求来知道在 PropertyGrid 中显示的类型- 因为这接受 object ,给它什么BinaryFormatter提供。您在那里看到了具体问题吗?同样,您可能需要检查 IList (非通用)- 但不值得担心 IList<T> ,因为这不是 PropertyGrid检查!

您当然可以找到 T如果您想要 ( like so ) - 并使用 MakeGenericType()Activator.CreateInstance - 不漂亮。


好的;这是一种使用自定义描述符的方法,涉及了解有关对象或列表类型的任何;如果您真的希望可以将列表项直接扩展到属性中,那么在此示例中您会看到 2 个假属性(“Fred”和“Wilma”)——这是额外的工作,虽然;-p

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

class Person
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }

public override string ToString() {
return Name;
}
}

static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Person fred = new Person();
fred.Name = "Fred";
fred.DateOfBirth = DateTime.Today.AddYears(-23);
Person wilma = new Person();
wilma.Name = "Wilma";
wilma.DateOfBirth = DateTime.Today.AddYears(-20);

ShowUnknownObject(fred, "Single object");
List<Person> list = new List<Person>();
list.Add(fred);
list.Add(wilma);
ShowUnknownObject(list, "List");
}
static void ShowUnknownObject(object obj, string caption)
{
using(Form form = new Form())
using (PropertyGrid grid = new PropertyGrid())
{
form.Text = caption;
grid.Dock = DockStyle.Fill;
form.Controls.Add(grid);
grid.SelectedObject = ListWrapper.Wrap(obj);
Application.Run(form);
}
}
}

[TypeConverter(typeof(ListWrapperConverter))]
public class ListWrapper
{
public static object Wrap(object obj)
{
IListSource ls = obj as IListSource;
if (ls != null) obj = ls.GetList(); // list expansions

IList list = obj as IList;
return list == null ? obj : new ListWrapper(list);
}
private readonly IList list;
private ListWrapper(IList list)
{
if (list == null) throw new ArgumentNullException("list");
this.list = list;
}
internal class ListWrapperConverter : TypeConverter
{
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(
ITypeDescriptorContext context, object value, Attribute[] attributes) {
return new PropertyDescriptorCollection(
new PropertyDescriptor[] { new ListWrapperDescriptor(value as ListWrapper) });
}
}
internal class ListWrapperDescriptor : PropertyDescriptor {
private readonly ListWrapper wrapper;
internal ListWrapperDescriptor(ListWrapper wrapper) : base("Wrapper", null)
{
if (wrapper == null) throw new ArgumentNullException("wrapper");
this.wrapper = wrapper;
}
public override bool ShouldSerializeValue(object component) { return false; }
public override void ResetValue(object component) {
throw new NotSupportedException();
}
public override bool CanResetValue(object component) { return false; }
public override bool IsReadOnly {get {return true;}}
public override void SetValue(object component, object value) {
throw new NotSupportedException();
}
public override object GetValue(object component) {
return ((ListWrapper)component).list;
}
public override Type ComponentType {
get { return typeof(ListWrapper); }
}
public override Type PropertyType {
get { return wrapper.list.GetType(); }
}
public override string DisplayName {
get {
IList list = wrapper.list;
if (list.Count == 0) return "Empty list";

return "List of " + list.Count
+ " " + list[0].GetType().Name;
}
}
}
}

关于c# - 当我不知道 (T) 的类型时如何反序列化通用列表 <T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1804859/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com