首页 > 解决方案 > 将对象动态转换为基本类型

问题描述

假设我有一个未知类型的对象,
object obj
我可以使用它来获取它的基类型obj.GetType().BaseType,但是如何继续转换obj为这种基类型?

语境:

就我而言,我正在编写一个 Serialize 方法,该方法使用看起来像这样的反射将任何对象序列化为字符串

public static string Serialize(this object obj)
{
    string _serialization;
    foreach (field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public))
    {
        _serialization += field.value
    }
    return _serialization;
}

我的问题尤其是你不能从基类型中获取私有字段GetFields(),所以我想要做的是转换field.value为它的基类型,以便能够访问这些字段并递归序列化所有父类型obj
所以我想要能够做的基本上是

foreach (baseType in field.value.baseTypes)
{
    serialization += field.value.ConvertToBaseType().Serialize()
}

我能想到的只是,Convert.ChangeType(object, Type)但我得到一个例外,说object需要实施IConvertible,并且IConvertible在我的项目中的所有内容中实施都不是一种选择。此外,我认为此方法适用于 .net 框架类型和值类型。

这篇文章中的所有代码都是用于重新创建我的情况的示例代码,因为它的规模要大得多,我不能在这里转储所有代码。

编辑:这不是该帖子的重复,因为即使我的上下文相似,我也有一个完全不同的问题。
我的问题根本没有直接的解决方案,所以我将关闭它。

标签: c#serializationdynamictypespolymorphism

解决方案


不,您不能在执行时更改对象的类型,也没有任何内置方式可以说“创建基本类型的新对象,但从派生类型的这个实例中复制所有字段值”。

但我真的不认为你需要 - 至少不是你所描述的你想要这样做的原因:

我的问题尤其是您无法使用 GetFields() 从基本类型中获取私有字段

是的,你可以 - 你只需要确保你要求非公共领域以及公共领域。这是一个示例,显示了层次结构中的所有字段,包括它们在特定实例中的值:

using System;
using System.Reflection;

class Base
{
    private int x = 10;    
}

class Derived : Base
{
    private int y = 20;
}

class Program
{
    static void Main()
    {
        object instance = new Derived();
        var type = instance.GetType();
        while (type != null)
        {
            Console.WriteLine($"Fields in {type}:");
            var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            foreach (var field in fields)
            {
                Console.WriteLine($"{field.Name}: {field.GetValue(instance)}");
            }
            type = type.BaseType;
        }
    }
}

这段代码的输出是:

Fields in Derived:
y: 20
Fields in Base:
x: 10
Fields in System.Object:

请注意,这x是基类中的私有字段,但仍会根据需要显示在输出中。

所以你的Serialize方法需要一个类似的循环来遍历完整的类层次结构,序列化所有类型的所有字段。(我注意到在序列化中还有很多其他复杂的事情需要考虑,例如引用标识处理和循环,但这是另一回事。如果您可以编写自己的序列化程序代码而摆脱困境,我强烈建议您这样做.)


推荐阅读