- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以没有混淆,当我讨论我的问题时,我是以使用由 Bond 模式产生的编译类的人的身份这样做的(也就是说我使用“类”而不是“结构”等) .我觉得这样想在认知上更有意义。
我正在使用 Microsoft Bond,我有一个主类,它有几个属性,其中一个是派生类的实例。
创建主类的实例时,我可以毫无问题地将属性设置为派生类的实例;然而,当我从二进制反序列化回主类时,该属性现在被视为它的基类。
我曾尝试将其转换为派生类,但会抛出运行时异常。
Bond 文档/手册中使用派生类的示例让您在反序列化时指定派生类,但我不只是反序列化派生类,而是反序列化主类。
这是我如何设置绑定(bind)模式的示例
struct BaseExample
{
0: int property1;
}
struct DerivedExample : BaseExample
{
0: int property2;
}
struct MainExample
{
0: BaseExample mainProperty;
}
在使用中,我将 mainProperty 设置为 DerivedExample 类的一个实例。我期望的是,在反序列化之后,mainProperty 仍然是 DerivedExample 类型(包含 property2),但我看到的是 mainProperty 是 BaseExample 类型(并且不包含 property2)
我是被迫使用泛型来做这件事还是我遗漏了什么?
编辑:添加示例
我使用从 Bond 模式生成的类的代码是这样的。
我们有一个调用服务来创建这种类型的消息,并使用 Bond 将其序列化为字节数组,然后再通过流发送。
var message = new MainExample();
var derivedExample = new DerivedExample()
{
property1 = 1,
property2 = 2,
};
message.mainProperty = derivedExample;
// This block is all from the Bond examples
var output = new OutputBuffer();
var writer = new CompactBinaryWriter<OutputBuffer>(output);
Serialize.To(writer, message);
SendMessage(output.Data.Array);
现在我们有一个接收服务,它将把这个消息从流中取出并使用 Bond 将它反序列化回一个对象。
void HandleMessage(byte[] messageBA)
{
// This block is all from the Bond examples
var input = new InputBuffer(messageBA);
var reader = new CompactBinaryReader<InputBuffer>(input);
MainExample message = Deserialize<BondEvent>.From(reader);
// mainProperty is now of type BaseExample and not DerivedExample
message.mainProperty.property1; // is accessable
message.mainProperty.property2; // will not compile
DerivedExample castedProperty = message.mainProperty as DerivedExample; // fails at runtime
}
完全披露:我实际上使用的是 F#,但我认为在 C# 中执行这些操作会更好
最佳答案
您在反序列化时观察到的切片行为在写入的模式中是预期的。 MainExample.mainProperty
字段类型为 BaseExample
,所以当它被序列化时,只有 BaseExample
字段被写入。使用哪种运行时类型并不重要。此外,反序列化时,只有 BaseExample
字段将被实现。
在处理继承和多态性时,Bond 不在序列化有效负载中包含任何类型信息:它将如何建模的决定留给模式设计者。这源于 Bond 只为使用的东西付费的理念。
根据您建模的数据,我看到了两种设计架构的方法:
bonded
如问题中所述,MainExample
结构可以被通用化:
struct MainExample<T>
{
0: T mainProperty;
}
这基本上可以让您轻松创建一堆具有相似形状的不同结构。但是这些结构不会有"is"关系。类似 HandleMessage
的方法可能还必须是通用的,从而导致通用级联。
要在另一个类型多态的结构中包含一个字段,请将该字段设置为 bonded
field .绑定(bind)字段在序列化时不切片。此外,它们不会立即反序列化,因此接收方有机会选择合适的类型进行反序列化。
在 .bond 文件中,我们有这个:
struct MainExample
{
0: bonded<BaseExample> mainProperty;
}
要序列化,请执行以下操作:
var message = new MainExample();
var derivedExample = new DerivedExample()
{
property1 = 1,
property2 = 2,
};
message.mainProperty = new Bonded<DerivedExample>(derivedExample);
// NB: new Bonded<BaseExample>(derivedExample) WILL slice
反序列化:
void HandleMessage(byte[] messageBA)
{
// This block is all from the Bond examples
var input = new InputBuffer(messageBA);
var reader = new CompactBinaryReader<InputBuffer>(input);
MainExample message = Deserialize<BondEvent>.From(reader);
DerivedExample de = message.mainProperty.Deserialize<DerivedExample>();
}
使用 bonded
时多态性的字段,我们需要有一些方法来知道要反序列化到哪个派生类型。有时这是从有效载荷外部的上下文中获知的(例如,可能处理的每个消息只有一种类型)。其他时候,我们需要将此信息嵌入有效负载的公共(public)部分。一种常见的方法是使用枚举:
enum PropertyKind
{
Base;
Derived;
}
struct MainExample
{
0: bonded<BaseExample> mainProperty;
1: PropertyKind mainPropertyKind = Base;
}
在 C# polymorphic_container 中有一个执行这种分派(dispatch)的完整示例。 Bond 存储库中的示例。
OutputBuffer.Data.Array
我注意到在发送消息的代码中,有以下一行,其中包含一个错误:
SendMessage(output.Data.Array);
OutputBuffer.Data
属性是 ArraySegment<byte>
,用于表示其他数组的一部分。此切片可能比整个数组(Count
属性)短,并且它可能从 0 以外的偏移量开始(Offset
属性)。大多数 I/O 库都有像 SendMessage(byte[] buf, int offset, int count)
这样的重载可以在这种情况下使用。
支持 OutputBuffer
的默认数组是 65K,所以几乎可以肯定发送了一堆额外的数据。
关于c# - 如何正确使用派生类作为 Microsoft Bond 对象的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42075814/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!