假设我有一个类型未知的对象
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框架类型和值类型。
这篇文章中的所有代码都是用于重现我的情况的示例代码,因为它规模更大,我不能只在此处转储所有这些代码。
编辑:
这不是that post的副本,因为即使我的情况相似,我也有完全不同的问题。
根本没有直接解决我的问题的方法,所以我将其解决。
答案 0 :(得分:2)
不,您不能在执行时更改对象的类型,也没有内置的说法:“创建基本类型的新对象,而是从派生类型的该实例复制所有字段值。 ”
但是我真的不认为您需要-至少不需要像您所说的那样做:
特别是我的问题是,您无法使用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
方法需要一个类似的循环来遍历完整的类层次结构,对所有类型的所有字段进行序列化。 (我注意到,在序列化中还有很多其他复杂的事情要考虑,例如引用标识处理和循环,但这是另一回事。如果您可以不编写自己的序列化程序代码而逃脱,我强烈建议您这样做。)
答案 1 :(得分:1)
Type tt = typeof (obj).BaseType;
foreach (FieldInfo fi in tt.GetFields())
{
fi.GetValue(obj);
}