是否可以在 .NET 代码中找到所有具体类型的泛型方法调用?



我正在编写一个用于序列化对象的 C# 代码生成器,以便通过网络发送它们。

起点是这个(简化(:

public static partial class Serialization
{
public static void Serialize<T>(in T value, DataStream stream)
{
throw new NotImplementedException($"Don't know how to serialize type {typeof(T)}!");
}
public static void Deserialize<T>(out T target, DataStream stream)
{
throw new NotImplementedException($"Don't know how to deserialize type {typeof(T)}!");
}
}

现在序列化代码生成器将为需要序列化的所有类型生成额外的非泛型SerializeDeserialize方法,例如对于具有公共float字段的结构Vector3xyz

public static partial class Serialization
{
// automatically generated method
public static void Serialize(in Vector3 value, DataStream stream)
{
stream.Write(value.x);
stream.Write(value.y);
stream.Write(value.z);
}
// automatically generated method
public static void Deserialize(out Vector3 target, DataStream stream)
{
target.x = stream.ReadFloat();
target.y = stream.ReadFloat();
target.z = stream.ReadFloat();
}
}

开头所示的泛型方法仅用于防止在尚未为类型生成序列化代码的情况下出现编译器错误。我需要代码来编译,因为否则我不能对它使用反射。

目前,我必须使用自定义EnableSerialization属性标记需要序列化代码的类型。

理想情况下,生成器将查看编译的代码(使用静态代码分析(,确定可能传递给泛型SerializeDeserialize方法的类型,然后为这些类型生成代码。因此,例如,如果我在代码中的某个地方有这个:

int x = 42;
Serialization.Serialize(x, new DataStream());

然后,代码生成器应选取int作为需要序列化代码的类型。

是否有任何用于这种努力的方法,或者 .NET 库或第三方库中是否有任何可以促进这一点的方法?

(我已经考虑过运行时代码生成,但我更喜欢将其作为预处理步骤。

>使用Mono.Reflection,您可以执行以下操作:

HashSet<Type> types = new HashSet<Type>();
Assembly assembly = Assembly.LoadFile(@"<Path>");
foreach (Module module in assembly.GetModules())
{
foreach (Type type in module.GetTypes())
{
// GetMethodBody() should not be null since otherwise Disassembler.GetInstructions would throw an exception
foreach (MethodInfo method in type.GetMethods().Where(m => m.GetMethodBody() != null))
{
foreach (Instruction instruction in Disassembler.GetInstructions(method))
{
// instruction.Operand being MethodInfo most probably means a call instrution.
// Not sure if this always true
MethodInfo called = instruction.Operand as MethodInfo;
if (called != null && called.DeclaringType.Name.Equals("Serialization") && called.Name.Equals("Serialize"))
{
types.Add(called.GetParameters()[0].ParameterType);
}
}
}
}
}

DisassemblerInstruction都是Mono.Reflection的一部分。
现在,您已将使用的所有类型传递给types中的Serialization.Serialize

相关内容

  • 没有找到相关文章

最新更新