C#中C++的reinterpret_cast等价我想知道C#中C++的reinterpret_cast等价什么?这是我的示例:classBase{protectedintcounter=0;}classFoo:Base{publicintCounter{get{returncounter;}}}基地b=新基地();Foof=b作为Foo;//f将为null我不反对为什么f应该为null,因为它应该是。但如果是C++,我可以写Foof=reinterpret_cast(b);得到我想要的。我该怎么做才能在C#中实现相同的目标?附言。我假设Base和Foo在数据方面是一致的。[更新]这是一个reinterpret_cast可能有帮助的简单场景:考虑编写一个XXX-RPC库,您无法控制传入的参数,也无法控制被调用服务的签名。您的图书馆应该使用给定的参数调用请求的服务。如果C#支持reinterpret_cast,我可以简单地将给定参数reinterpret_cast为预期参数并调用服务。讨论正如一些答案所指出的,.Net在问题范围内严格执行类型安全。reinterpret_cast本质上是不安全的操作,因此实现它的可能方法可能是通过反射或序列化,这两者是相关的。正如您在更新中提到的,可能的用途是RPC框架。RPC库通常使用序列化/反射,并且有几种可用:因此,您可能不想自己编写一个。如果你的类Base使用公共属性,你可以使用AutoMapper:classBase{publicintCounter{get;放;}//...}...AutoMapper.Mapper.CreateMap();Foofoo=AutoMapper.Mapper.Map(b);Foo根本不需要从Base派生。它只需要将您感兴趣的属性映射到。但同样,您可能根本不需要这两种类型——重新考虑架构可能是解决方案。一般来说,不需要使用reinterpret_cast,它是一个干净的架构,非常适合.NetFramework中使用的模式。如果您仍然受困于此,这里有一个使用紧凑序列化库protobuf-net的解决方案。您班级的序列化解决方案:usingSystem;使用System.IO;使用ProtoBuf;使用ProtoBuf.Meta;[ProtoContract][ProtoInclude(3,typeof(Foo))]classBase{[ProtoMember(1)]protectedintcounter=0;publicBase(intc){counter=c;}publicBase(){}}[ProtoContract]classFoo:Base{publicintCounter{get{returncounter;}}}和一个可运行的序列化——反序列化??示例:classProgram{staticvoidMain(string[]args){Baseb=newBase(33);使用(MemoryStreamstream=newMemoryStream()){Serializer.Serialize(stream,b);Console.WriteLine("长度:{0}",stream.Length);stream.Seek(0,SeekOrigin.Begin);Foof=newFoo();RuntimeTypeModel.Default.Deserialize(stream,f,typeof(Foo));Console.WriteLine("Foo:{0}",f.Counter);}}}outputsLength:2Foo:33如果你不想在你的合同中声明派生类型,请看这个例子......正如你所看到的,序列化非常紧凑。如果想使用更多的字段,可以尝试隐式序列化字段:[ProtoContract(ImplicitFields=ImplicitFields.AllFields)]一般的reinterpret_cast肯定可以通过这种序列化方案来实现,或者直接通过反射来实现,但是我现在不会投入时间。这很好用。是的,它和你想象的一样邪恶和可怕。staticunsafeTDestReinterpretCast(TSourcesource){varsourceRef=__makeref(source);vardest=default(TDest);vardestRef=__makeref(dest);*(IntPtr*)&destRef=*(IntPtr*)&sourceRef;返回__refvalue(destRef,TDest);需要注意的一件事是,如果您要将T[]转换为U[]:您可能能够在C#中使用不安全块和void*:unsafestaticTResultReinterpretCast(thisTOoriginaloriginal)whereTOriginal:struct实现类似的行为其中TResult:struct{return*(TResult*)(void*)&original;用法:Barb=newBar();Foof=b.ReinterpretCast();f=ReinterpretCast(b);//这在未经测试的情况下同样有效。我想,结构约束会使您的问题无效,但它们是必需的,因为类由GC管理,因此您不能指向它们。C#在允许您执行此操作的类型系统中没有漏洞。它知道某物是什么类型,并且不允许您转换为其他类型。原因很明显。当你向Foo添加一个字段时会发生什么?如果你想要一种Foo,你需要创建一种Foo。可能更好的方法是创建一个以Base作为参数的Foo类型的构造函数。这是我的“实现”/whereTOoriginal:struct//whereTResult:struct{returnRead(AddressOf(orig));确保在调用时知道自己在做什么,尤其是引用类型。因为b只是Base的一个实例,所以它永远不能转换为Foo的非空实例。也许界面可能更适合您的需求?如果Foo和Bar是结构,你可以做[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]publicclassMyFooBarHelper{[System.Runtime.InteropServices.FieldOffset(0)]publicFootheFoo;[System.Runtime.InteropServices.FieldOffset(0)]publicBartheBar;但我不确定这是否适用于对象。以上就是C#学习教程:相当于C#中C++的reinterpret_cast分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
