小编Pau*_*ham的帖子

.Net Framework 4.0 - Opcodes.Box存在于Dictionary中,带有int键

我正在尝试调查带有枚举键的字典是否仍然在较新版本的.Net中产生垃圾(比如说> = 4)

请参阅Shawn Hargreaves博客文章,了解为何我甚至为此烦恼......(http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage -collector-nirvana.aspx)非常具体我知道但是xbox上的垃圾是/可能是一个非常棘手的问题.

我创建了一个小的.Net v4控制台应用程序,比较为Dictionary和Dicationary生成的IL,并注意到两组代码中的"盒子"操作码,这让我很困惑.

.method private hidebysig 
    instance int32 FindEntry (
        !TKey key
    ) cil managed 
{
    // Method begins at RVA 0x61030
    // Code size 138 (0x8a)
    .maxstack 3
    .locals init (
        [0] int32,
        [1] int32
    )

    IL_0000: ldarg.1
    IL_0001: box !TKey   <----Hmmmm!
    IL_0006: brtrue.s IL_000e

    IL_0008: ldc.i4.5
    IL_0009: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)

    IL_000e: ldarg.0
    IL_000f: ldfld int32[] class System.Collections.Generic.Dictionary`2<!TKey, !TValue>::buckets
    IL_0014: brfalse.s IL_0088
Run Code Online (Sandbox Code Playgroud)

https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.box%28v=vs.110%29.aspx

将值类型(在valTypeToken中指定的类型)转换为真实对象引用.

这里的盒子不是堆分配吗?如果没有,那么我怎么知道何时存在可能导致Xbox崩溃的堆分配?(从查看IL)它是否依赖于其他一些上下文?内存分析器(例如CLR Profiler)是唯一可以确定的方法吗?

.net c# dictionary xbox360 garbage

6
推荐指数
1
解决办法
199
查看次数

.Net序列化 - 将[Serializable]与继承树中的自定义混合

我正在将Java游戏转换为C#(Puppy Games的Titan Attacks),除了上一个任务是保存文件的游戏状态序列化之外,我现在已经完成了很多工作.

典型层次结构:资源(基础) - >功能 - >屏幕/效果/实体 - > GameScreen/LaserEffect/Invader

Java代码使用标准的ObjectOutputStream/ObjectInputStream来执行二进制序列化,但是在基类级别(Resource)上烦人地执行一些readResolve/writeResolve工作来自定义序列化过程(如果资源被命名,它不会序列化它并只是返回一个代理使用稍后用于从hashmap中获取资源的名称).

我天真的解决方案是盲目地复制这种方法并在基类中实现ISerializable来覆盖TYPE ......

public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
    if (name != null) {
        // Got a name, so send a SerializedResource that just references us
        info.AddValue("name", this.name);
        info.SetType(typeof(SerializedResource));
        return;
    }

    //Serialize just MY fields (defined in Resource)
    this.SerializeMyFields(info, context, typeof(Resource));
}
Run Code Online (Sandbox Code Playgroud)

Q)所以,我很确定所有的注意都是内置序列化的,我必须在继承链中一直实现ISerializable以及序列化构造函数?

注意GetObjectData是虚拟的,因此派生类可以序列化它们的字段,然后调用基类.这有效,但是增加很多课程(100s)是一项繁琐的工作.

一些派生类型(Sprite,InvaderBehaviour等)也执行自定义序列化工作,以使事情变得更糟.

我查看了Jeffrey Richter关于这个主题的文章,并尝试使用ResourceSurrogateSelector:ISerializationSurrogate类型构造,但是如果被序列化的类型是Resource而不是从资源派生的类型(即不会被称为序列化),那么只会调用这些序列化方法入侵者或游戏画面)

问)有一种聪明的方法吗?

我已经设法保持两个代码库彼此非常接近,这使转换变得更容易 - 我想在这里继续这种方法(所以没有XmlSerializer,Protobuf等),除非有一个非常令人信服的理由不至.

我已经考虑过编写一些Java来自动化这个过程,并反映实现Serializable接口的类型,并创建一个包含所有.Net序列化代码的.cs文件,这样我就不会污染主类文件(我是让他们偏袒)

PS - 目标平台将是.Net方面的Windows8/Surface/XBox360(版本4),可能是PS Vita/iOS使用Mono.保存在序列化的平台上反序列化.

编辑 Sergey Teplyakov在这篇文章中的回答.... .NET,C#:如何添加一个充当ISerializable接口的自定义序列化属性 ...让我进入了ISurrogateSelector接口,看起来它有助于选择所需的派生类.

.net binary serialization hierarchy

5
推荐指数
1
解决办法
613
查看次数

标签 统计

.net ×2

binary ×1

c# ×1

dictionary ×1

garbage ×1

hierarchy ×1

serialization ×1

xbox360 ×1